Arc Forumnew | comments | leaders | submit | rocketnia's commentslogin
3 points by rocketnia 4251 days ago | link | parent | on: Iso

No offense, but I'd like to give your comment an awful lot of errata:

Those objects you're creating will have the cons list (quote a) as a key. Non-atomic keys are full of gotchas because Arc's tables use use Racket's 'equal? for key comparison, rather than using 'is or 'iso. This means tables care whether a list ends in the symbol 'nil or the Racket empty list (), which is a detail that's otherwise invisible in Arc.

(If you want the symbol 'a as a key, the code is (obj a 'b).)

Arc's tagged types are not lists, and 'iso can support lists without supporting tagged types. (Personally, I wouldn't want 'iso to dig around in my tagged types anyway. I like pretending the data inside is encapsulated, except where my code absolutely needs to access it.)

Finally, does 'iso actually support tables in Anarki? I can't try it out right now, but I don't see any code for this when I search GitHub.

-----

2 points by akkartik 4251 days ago | link

Errata gratefully accepted :) I blame interference from wart. I was running anarki while I wrote this comment, but clearly I wasn't running it enough.

"Finally, does 'iso actually support tables in Anarki? I can't try it out right now, but I don't see any code for this when I search GitHub."

It's in a defextend clause (https://github.com/arclanguage/anarki/blob/becefed840/arc.ar...) followed immediately by support for tagged types.

  (defextend iso (x y) (isa x 'table)
    (and (isa x 'table)
         (isa y 'table)
         (is (len keys.x) (len keys.y))
         (all
           (fn ((k v))
             (iso y.k v))
           tablist.x)))

  ; default impl for tagged types
  (defextend iso (a b) ($.vector? a)
    (iso ($.vector->list a)
         ($.vector->list b)))
Does the 'default impl' trigger your gag reflex? :)

-----

2 points by rocketnia 4250 days ago | link

Oops, I assumed Github's search would show me every occurrence in every file, like a recursive grep. No such luck, I guess. :-p So you got me.

While that's a reasonably useful default behavior for 'iso on tagged types, I'm not particularly happy to see it.

Arc provides very few helper utilities for working with tagged types--basically just the axioms 'annotate, 'type, and 'rep, plus 'isa and 'coerce--and the documented purpose of tagged types is for user-defined types. I came to Arc from a more OO-like background and saw this as a good way to control access to the implementation details of my types. Unless you explicitly called 'rep, you didn't get more coupling than you bargained for. This gave 'rep almost an "unsafe" reputation for me.

If 'iso gets to access the rep at will, then I may have been programming in Arc less robustly than I expected: Either each of my types should have come with an 'iso extension to reinforce my encapsulation, or I should have considered 'iso "unsafe" and used it less often. Not that I could have known this at the time! :)

But it's not a big deal. I do deep comparison operations sparingly enough as it is, and I don't know if my soft encapsulation technique actually matters because I rarely saw anyone else following similar guidelines. (I've rarely seen anyone using 'annotate at all, actually, and I think it's been a common complaint that 'annotate is basically 'cons with fewer utilities built up around it. That's a plus for me, I guess, lol.)

A good example of me considering an operation "unsafe" is earlier in this thread, where I discouraged the use of compound values as table keys. It just so happens Arc's table key comparison breaks the encapsulation of tagged types as well. :)

-----

2 points by rocketnia 4261 days ago | link | parent | on: Pg is "going to check out of HN"

pg: "Comments get from pending to live by being endorsed by multiple HN users with over 1000 karma."

Funnily enough, akkartik, you're the only recent poster with that much karma. XD

-----

2 points by akkartik 4261 days ago | link

No danger of it happening here. Arc forum is running some ancient version from what I can tell. They probably learned to stop messing with it after the voting ring detector went haywire. I wonder how many of us remember that :)

-----


The error "Invalid cross-device link" happens if you're trying to move a file across partitions. Apparently sometimes people have set up their home directory in a separate partition, even without realizing it.[1] So I'm guessing you're in a situation like that.

Other languages seem to recover from this particular error and do a copy and unlink instead:

Python: https://mail.python.org/pipermail/python-list/2005-February/...

Ruby: http://stackoverflow.com/questions/403239/how-do-i-move-a-fi...

Racket's reference for 'rename-file-or-directory states that it can move files to other paths "on the same disk"[2], and it goes into detail about atomicity guarantees, so this behavior is probably by design.

So the way you can find resolution here might be:

- Somehow change what temp directory Arc uses.

- Put the Arc directory elsewhere on your filesystem.

- Somehow change your partitions so the home directory and temp directory are in the same one.

- We should probably update Arc to recover from this somehow. :)

---

[1] http://www.linuxquestions.org/questions/linux-newbie-8/inval... (Warning: This page has lots of ads, and there's some flaming with harsh language.)

[2] http://docs.racket-lang.org/reference/Filesystem.html

-----

3 points by cooler 4264 days ago | link

Thanks you for your help.

1. "...So I'm guessing you're in a situation like that."

Yes,you are right.

2. "- Somehow change what temp directory Arc uses."

I don't know how to.

3. "- Somehow change your partitions so the home directory and temp directory are in the same one."

This worked.

BTW, I have tried the old arc3.1 version, but it didn't have the problem.

-----

2 points by akkartik 4263 days ago | link

For future reference, I figured out how to change the temp directory arc/racket uses:

  $ TMPDIR=~/tmp arc.sh
The TMPDIR must exist, otherwise racket will again fall back to defaults.

-----

1 point by akkartik 4264 days ago | link

Ack, accidental downvote. So the 'presence indicator' should really be 3.

-----


Does this tool find Arcueid? :) That project's on GitHub too.

https://github.com/dido/arcueid

-----

3 points by svetlyak40wt 4273 days ago | link

Tried arcueid. It is unstable. For example, running this simple code:

  (thread (while t (prn "Still going")))
Ends very quickly with error like this:

  arcueid: cont.c:54: __arc_mkcont: Assertion `(((struct vmthread_t *)(((struct cell *)(thr))->_obj))->spr) > (((struct vmthread_t *)(((struct cell *)(thr))->_obj))->stkbase)' failed.
  zsh: abort      ~/tmp/arcueid-base/bin/arcueid

-----

2 points by svetlyak40wt 4273 days ago | link

I've changed the test to count iterations:

  (thread (let i 0 (while t (prn "Still going: " i) (++ i))))
and it every time broke on 7270 iteration.

-----

2 points by svetlyak40wt 4273 days ago | link

Recursive code like this:

  (def my-loop ((o i 0)) (prn "Still going: " i) (my-loop (++ i)))
  (my-loop)
Performs much better. It fails only after 21799 iteration:

  Still going: 21799
  arcueid: env.c:83: __arc_mkenv: Assertion `(((struct vmthread_t *)(((struct cell *)(thr))->_obj))->spr) > (((struct vmthread_t *)(((struct cell *)(thr))->_obj))->stkbase)' failed.
  Still going: zsh: abort      ~/tmp/arcueid-base/bin/arcueid
:(

-----

1 point by akkartik 4273 days ago | link

I think all the errors you're seeing are due to running out of heap. How much memory do you have? Is there some per-process limit, perhaps to RLIMIT_AS?

Edit 35 minutes later. I can reproduce that it dies for me at the precise same iteration as you. And RLIMIT_AS is infinity, so that's not the issue. I've pinged the author for comment.

-----

2 points by svetlyak40wt 4271 days ago | link

Thank you. But now I think it would be wise not to complain about the issue on the forum, but rather to create an issue on the project's github. Will do it now.

Update: done — https://github.com/dido/arcueid/issues/60

-----

2 points by dido 4269 days ago | link

Well, thanks for the bug report. Well, I'll look into it when I have the time: the work which pays my bills has caught up with me once again and I don't have a lot of time to do hobby development. :)

-----

2 points by svetlyak40wt 4273 days ago | link

Well, actually, even without threading, arcueid running code:

  (let i 0 (while t (prn "Still going: " i) (++ i)))

Fails with exception:

  arcueid: cont.c:58: __arc_mkcont: Assertion `(((struct vmthread_t *)(((struct cell *)(thr))->_obj))->spr) > (((struct vmthread_t *)(((struct cell *)(thr))->_obj))->stkbase)' failed.
after 7266 iterations.

-----

2 points by dido 4269 days ago | link

The assertion error is a stack overflow. :) At present Arcueid makes use of a fixed-size stack within its virtual machine, and since the compiler still can't properly optimise tail recursion, your code overflows the stack.

-----

1 point by akkartik 4269 days ago | link

That was what I thought :) Is there a place where I can increase the size of the fixed stack? I looked for the limit in the code, but couldn't find it.

-----

3 points by dido 4268 days ago | link

src/vmengine.h:236:

#define TSTKSIZE 65536

Increase it as high as you like. :)

-----

1 point by akkartik 4268 days ago | link

Thanks!

Does it make sense to resize it on the fly when we discover we've overflowed the stack? Or are there potentially continuation pointers into the stack that would be non-trivial to track down?

-----

1 point by akkartik 4268 days ago | link

Yeah, no luck: https://github.com/akkartik/arcueid/commit/ae31b82540

-----

1 point by akkartik 4259 days ago | link

Possibly relevant: http://wingolog.org/archives/2014/03/17/stack-overflow

-----

3 points by svetlyak40wt 4276 days ago | link

Well, I haven't tried to run crawler with large depth setting yet. I discovered, that it have strange problems with threading and almost unable to process in parallel. Then I tried to investigate why. Will make a separate post on it, when will get some valuable information.

-----

2 points by rocketnia 4277 days ago | link | parent | on: An update on wart

In case it helps (or just drives a discussion), I've ironed out my own design spec for the features you're going for.

It's not quite the same as what you're describing. For one thing, it doesn't include the new restrictions you're talking about.

For another thing, it includes a new pattern type. Symbols have a lot of duties in your patterns because they deal with evaluation and keywords. I found it easiest to separate symbol patterns into two different types of patterns, only one of which deals with keywords. The non-keyword patterns I represent as strings (just to distinguish them from symbols). It would be easy to replace this with a special form or with some other literal type.

...Oh, I guess you don't have an explicit keyword parameter syntax either. I assumed you did, so it's in here too. (It could actually help clarify what's going on here. The symbol pattern deals with keywords and does just a bit more on top of that, so I like the side-by-side comparison.)

---

The pattern language has several kinds of patterns. A pattern operates on a single unevaluated s-expression (henceforth "expr") and an evaluation environment, and it outputs a map of variable bindings. It also outputs an evaluation result, if it evaluates the expr as part of its processing. (The evaluation result is only used for (<a> | <b>) patterns, to prevent duplicate evaluations.)

These are the available patterns:

  <str>  ; where <str> is a string
Evals the current expr and binds the variable named <s> to the result value.

  <s>  ; where <s> is a symbol
Runs the pattern <str> on the current expr, where <str> is the string name of the symbol <s>.

Uses those variable bindings and that evaluation result.

(That may look simple enough, but a completely different symbol pattern applies when matching a list element. See below.)

  '<a>
Runs the pattern <a> on a quoted version of the current expr.

Uses all variable bindings produced by <a>.

  ()
Evals the current expr. If the result isn't nil, raises an error.

  ; any cons cell
Does several special things depending on the contents of the pattern's cons cell:

  (<a> | <b>)
Runs pattern <a> on the current expr.

If that pattern returned an evaluation result, runs pattern <b> on a quoted version of that result value. Otherwise, runs pattern <b> on the current expr.

Uses all variable bindings produced by <a> and <b>, preferring the bindings in <b>.

Uses the evaluation result of <a> or <b> if available, preferring the result of <b>.

  (<before...> <k> <v> ... <rest>)
    ; where <before...> is any number of non-keyword, non-symbol
    ; elements; <k> is a keyword; and <rest> could be anything,
    ; especially an improper list
This pattern treats the current expr as an unevaluated improper list, looking for the first occurrence of <k> with another element after it (which we will refer to as the value expr).

If the keyword binding is found: Matches <v> against the value expr. Matches <rest> against an alteration of the current expr, changed to remove the keyword and the value expr. Uses all variable bindings produced by <v> and <rest>, preferring the bindings in <rest>.

If the keyword binding is not found: Matches the pattern <rest> against the entire expr. Uses those variable bindings.

  (<before...> <s> ... <rest>)
    ; where <before...> is any number of non-keyword, non-symbol
    ; elements; <s> is a symbol; and <rest> could be anything,
    ; especially an improper list
Let <k> be the keyword with the same name as the symbol <s>, and let <str> be this name as a string.

This pattern treats the current expr as an unevaluated improper list, looking for the first occurrence of <k> with another element after it (which we will refer to as the value expr).

If the keyword binding is found: Matches <str> against the value expr. Matches <rest> against an alteration of the current expr, changed to remove the keyword and the value expr. Uses all variable bindings produced by <str> and <rest>, preferring the bindings in <rest>.

If the keyword binding is not found: Matches the pattern (<str> ... <rest>) against the entire expr. Uses those variable bindings.

  ; for any other kind of cons cell...
  (<a> ... <b>)
Evals the current expr. If the result isn't a cons cell, raises an error. Otherwise, runs the patterns <a> and <b> on quoted versions of the result's car and cdr.

Uses all variable bindings produced by <a> and <b>, preferring the bindings in <b>.

-----

1 point by rocketnia 4277 days ago | link

I found another mistake I made. In the two rules that use <before...> and <rest>, that <before...> should be used whenever the rule matches the remainder of the expr.

In particular, for symbols to work as positional args whenever there isn't a keyword, the symbol rule needs to fall back to (<before...> <str> ... <rest>), reflecting the original location of the symbol in the pattern. I just had it falling back to (<str> ... <rest>) for some reason.

---

  (<before...> <k> <v> ... <rest>)
    ; where <before...> is any number of non-keyword, non-symbol
    ; elements; <k> is a keyword; and <rest> could be anything,
    ; especially an improper list
This pattern treats the current expr as an unevaluated improper list, looking for the first occurrence of <k> with another element after it (which we will refer to as the value expr).

If the keyword binding is found: Matches <v> against the value expr. Matches <rest> against an alteration of the current expr, changed to remove the keyword and the value expr. Uses all variable bindings produced by <v> and <rest>, preferring the bindings in <rest>.

If the keyword binding is not found: Matches the pattern <rest> against the entire expr. Uses those variable bindings.

  (<before...> <s> ... <rest>)
    ; where <before...> is any number of non-keyword, non-symbol
    ; elements; <s> is a symbol; and <rest> could be anything,
    ; especially an improper list
Let <k> be the keyword with the same name as the symbol <s>, and let <str> be this name as a string. This pattern treats the current expr as an unevaluated improper list, looking for the first occurrence of <k> with another element after it (which we will refer to as the value expr).

If the keyword binding is found: Matches <str> against the value expr. Matches <rest> against an alteration of the current expr, changed to remove the keyword and the value expr. Uses all variable bindings produced by <str> and <rest>, preferring the bindings in <rest>.

If the keyword binding is not found: Matches the pattern (<str> ... <rest>) against the entire expr. Uses those variable bindings.

---

After this fix:

---

  (<before...> <k> <v> ... <rest>)
    ; where <before...> is any number of non-keyword, non-symbol
    ; elements; <k> is a keyword; and <rest> could be anything,
    ; especially an improper list
This pattern treats the current expr as an unevaluated improper list, looking for the first occurrence of <k> with another element after it (which we will refer to as the value expr).

If the keyword binding is found: Matches <v> against the value expr. Matches the pattern (<before...> ... <rest>) against an alteration of the current expr, changed to remove the keyword and the value expr. Uses all variable bindings produced by <v> and (<before...> ... <rest>), preferring the bindings in the latter.

If the keyword binding is not found: Matches the pattern (<before...> ... <rest>) against the entire expr. Uses those variable bindings.

  (<before...> <s> ... <rest>)
    ; where <before...> is any number of non-keyword, non-symbol
    ; elements; <s> is a symbol; and <rest> could be anything,
    ; especially an improper list
Let <k> be the keyword with the same name as the symbol <s>, and let <str> be this name as a string. This pattern treats the current expr as an unevaluated improper list, looking for the first occurrence of <k> with another element after it (which we will refer to as the value expr).

If the keyword binding is found: Matches <str> against the value expr. Matches the pattern (<before...> ... <rest>) against an alteration of the current expr, changed to remove the keyword and the value expr. Uses all variable bindings produced by <str> and (<before...> ... <rest>), preferring the bindings in the latter.

If the keyword binding is not found: Matches the pattern (<before...> <str> ... <rest>) against the entire expr. Uses those variable bindings.

-----

2 points by rocketnia 4277 days ago | link

Oops, in one of those rules I said <s> where I meant <str>. Here's the corrected version:

  <str>  ; where <str> is a string
Evals the current expr and binds the variable named <str> to the result value.

-----

1 point by akkartik 4277 days ago | link

The next one refers to s and str as well. Is that intended?

Also, I don't follow the distinction between the string case and the symbol case.

-----

2 points by rocketnia 4277 days ago | link

"The next one refers to s and str as well. Is that intended?"

Yes. Only <s> appears in the pattern itself, but the meaning of <str> is explained by "...where <str> is the string name of the symbol <s>."

---

"Also, I don't follow the distinction between the string case and the symbol case."

Did you see this part? -- "(That may look simple enough, but a completely different symbol pattern applies when matching a list element. See below.)"

A symbol which occurs in a list acts as a hybrid keyword/positional argument. A symbol by itself acts just like a string.

---

Sorry I'm being terse with this stuff. I found it hard to express my points in informal English, which is why I went with a spec document style in the first place.

Let's see...

My motive is to show you a way your desired features can be accomplished in an extensible ravioli style, rather than one big chunk of spaghetti. What you want is achievable with a simple enough collection of parser combinators, although sometimes their interfaces may be unusual due to expression evaluation being part of the parsing process.

For instance, in the system I gave, the parser combinators use a few unusual design patterns:

- The combinators must take in an evaluation environment.

- The combinators frequently quote a value so they can pass it off to another combinator that may eval it again. (I think I've seen you use this style before, actually.)

- The combinators must sometimes return the evaluated expression, just so that the (<a> | <b>) pattern can avoid double evaluation.

Another important point I'm making is that you probably don't need to reorder the argument list for the purposes of keyword arguments. My system instead (effectively) reorders the parameter pattern so the keywords are processed first.

I got this system a bit wrong because I don't support multiple keyword aliases for the same parameter. My (<a> | <b>) pattern instead binds multiple parameter variables to the same argument value, so I got that backwards.

-----

2 points by akkartik 4277 days ago | link

This seems really useful. I got the motivation off the bat, but I still don't understand the spec. Can you give an example session showing how functions are defined, and how they are called?

-----

2 points by rocketnia 4277 days ago | link

Okay, I'll give that a try. Let's say we're defining a function and using it like this:

  > (def foo '(a b)
      (list a b))
  > (foo (+ 1 1) (+ 2 2))
  ((+ 1 1) (+ 2 2))
Let's vary some things here:

  '(a b)             ; the parameter list
  (a b)              ; the args to (list ...)
  ((+ 1 1) (+ 2 2))  ; the args to (foo ...)
  ((+ 1 1) (+ 2 2))  ; the result
  
  (baz)
  (baz)
  ((+ 1 1))
  ; Error! Can't make the function call (2).
  
  '(a b c)
  (a b c)
  ((+ 1 1) :c (+ 3 3) (+ 2 2))
  ((+ 1 1) (+ 2 2) (+ 3 3))
  
  '(a :b b c)
  (a b c)
  ((+ 1 1) (+ 2 2))
  ; Error! Unbound variable b in expression (list a b c).
So I have some more kinks to work out, lol. I finally appreciate your predicament. :)

The (baz) issue is caused by the complexity of the fact that in a normal function call, each of the arguments should be evaluated, but the list of arguments shouldn't. So if the traditional Arc parameter list (baz) is a pattern, it should destructure an unevaluated list in such a way that the baz pattern inside operates on an evaluated version of the list's first element.

It would be a lot simpler if we wrote this argument list differently:

  > (def foo (baz) ...)  ; doesn't work
  > (def foo `(,baz) ...)
  > (def foo (arg-list baz) ...)
      ; where (arg-list ...) is a pattern special form
I think that last one is promising, because then we can just write (baz) and the macroexpansion of (def ...) can insert that into (arg-list baz) for us. Then we get to have slight differences between how parameter lists work and how list destructuring works.

As for the "unbound variable b" issue, I think that could be solved by having each pattern take an optional current expr, rather than a mandatory one. My exact implementation of this would probably vary substantially based on what else I was trying to do. I might want a guarantee of which variables will be bound by a pattern long before there's an actual argument list to match it against, for compilation purposes and such.

-----

2 points by rocketnia 4277 days ago | link

Whoops, I forgot alias support entirely! Ah well, I'll just leave it this way for now.

-----

4 points by rocketnia 4286 days ago | link | parent | on: How to see a full traceback in anarki?

I took a look at http://docs.racket-lang.org/reference/exns.html and found something that works.

Look for these lines in ac.scm:

                (display "Error: ")
                (write (exn-message c))
Replace them with this:

                ((error-display-handler) (exn-message c) c)
Before:

  arc> (+ 1 (fn))
  Error: "cadr: contract violation\n  expected: (cons/c any/c pair?)\n  given: '(fn)"
  arc> (def foo () (map [+ 1 (fn ())] list.nil))
  #<procedure: foo>
  arc> (foo)
  Error: "+: contract violation\n  expected: number?\n  given: #<procedure: foo>\n  argument position: 2nd\n  other arguments...:\n   1"
After:

  arc> (+ 1 (fn))
  cadr: contract violation
    expected: (cons/c any/c pair?)
    given: '(fn)
    context...:
     C:\mine\prog\repo\anarki\ac.scm:24:22: ac
     C:\Program Files (x86)\Racket\collects\racket\private\map.rkt:26:19: loop
     C:\mine\prog\repo\anarki\ac.scm:486:0: ac-call
     C:\mine\prog\repo\anarki\ac.scm:1218:4
  
  arc> (def foo () (map [+ 1 (fn ())] list.nil))
  #<procedure: foo>
  arc> (foo)
  +: contract violation
    expected: number?
    given: #<procedure: foo>
    argument position: 2nd
    other arguments...:
     1
    context...:
      map1
     C:\mine\prog\repo\anarki\ac.scm:1218:4
In these examples, the first error happens during macroexpansion, when the compiler is processing the 'fn special form. The second error happens at run time. They both recover to the REPL just fine.

The second stack trace doesn't include 'foo or 'map, but I bet that's because they made a call in tail position, leaving no trace of their stack frame. Let's change 'foo so it doesn't do that:

  arc> (def foo () (map [+ 1 (fn ())] list.nil) nil)
  *** redefining foo
  #<procedure: foo>
  arc> (foo)
  +: contract violation
    expected: number?
    given: #<procedure: foo>
    argument position: 2nd
    other arguments...:
     1
    context...:
      map1
      foo
     C:\mine\prog\repo\anarki\ac.scm:1218:4
Yep, looking good. :)

Arc seems to throw away source location information, but I think we could get that back too if we tried. It'll involve using Racket syntax objects somehow.

Thanks for speaking up about this. This seems like something that could help a lot of people. XD

-----

2 points by svetlyak40wt 4285 days ago | link

Wow, this is very helpful even without source locations!

-----

2 points by akkartik 4285 days ago | link

Indeed, this is wonderful. I've updated anarki.

-----

4 points by rocketnia 4291 days ago | link | parent | on: Is there a repository of Arc libraries?

Historically speaking, Arc was put forward as a language for experimentation. If you want to package up code in a squeaky clean format for others to use who don't care about implementation details, you're doing something other than experimentation; you're publishing a product people would supposedly rely on.

Moreover. not even the Arc language is stable (or so this website has always said). If it encouraged people to package up their stable code, that would prove deceptive once the whole foundation fell away. This happened to Anarki when Arc 3 was released; the community had built up lots of Arc 2 code, and not much of that was ported to work on Arc 3.

However, Arc is not without module systems. The first thing I did in Arc was build some namespace macros with explicit imports and exports for my own benefit (Lathe). Andrew Wilcox made "the hackinator" which I think could download Arc programs from a Web-hosted manifest file, most often from GitHub.

More recently, Arc/Nu is an Arc implementation with rich support for first-class namespaces, along with several utilities for modular loading of Arc code that's written in the usual sequence-of-commands style. Arc/Nu is probably the best platform to publish stable modules for, since it can load alternate namespaces to achieve backwards compatibility.

-----

2 points by svetlyak40wt 4291 days ago | link

Thank you for detailed answer, now reasons are more clear to me!

-----


"This idea has something in common with IDEs that highlight all occurrences of the word at the cursor."

This is a feature I miss when I can't have it. I bet this highlighting would really help when reading printed-out code or code examples on a blog.

---

Your approach isn't semantic, in the sense that it doesn't discriminate between similarly named variables based on the language's actual scoping rules, but I wouldn't worry about that too much. When I name two variables the same thing, they usually are related in some way. Sometimes they all hold the same value most of the time, or sometimes they all have the same syntactic significance (e.g. CPS callbacks), or if all else fails... they have the same name. ^_- If it annoys me that they're highlighted the same way, it probably also annoys me that they have the same name.

---

You may also be interested to know that Nulan (well, the last stable version of Nulan) highlights variables differently depending on whether they're macros, locals, or non-macro globals.

-----

1 point by akkartik 4314 days ago | link

Yeah I've run into this already. In the screenshot for my original solution I highlighted a variable called test. Oops, poor name. Trouble is that this change now causes poor names in tightly localized contexts to bleed through the entire codebase :/

There's two directions to solve this:

a) Automatically detect variables with long lifetimes (measured in lines) to highlight. Perhaps this is a refinement of highlighting for

  *globals*
b) A way to attach metadata on a per-function or per-fragment basis. Highlight test in this function but not elsewhere, etc.

-----

1 point by akkartik 4314 days ago | link

Heh, I just thought of a name for the plugin that turns the bug into a feature: synaesthesia.vim :)

-----

2 points by rocketnia 4314 days ago | link

There was some interesting discussion on that in the Reddit thread. :)

-----

2 points by akkartik 4314 days ago | link

You got me, that's where I stole the idea from.

-----

3 points by rocketnia 4317 days ago | link | parent | on: Arc nu / https

To do this, I expect there must be some Arc code that handles the necessary encryption. That code probably doesn't exist in Arc.

Taking a brief look for SSL or TLS in Racket, I see http://docs.racket-lang.org/openssl/ .[1]

In particular, ports->ssl-ports looks like it might be a big help here. In fact, it has an option for TLS, so I guess this is the right place to look. :)

[1] I also see "Using HTTPS" at (http://docs.racket-lang.org/continue/#(part._.Using_.H.T.T.P...) but that's for Racket's own continuation-based server framework, not a library Arc can easily use.

-----

3 points by rocketnia 4329 days ago | link | parent | on: Using racket libraries in Arc

Here's something that worked for me in Arc 3.1 and Anarki.

Add this toward the bottom of ac.scm so that it can use the xdef syntax defined earlier in the file:

  (require racket/class)
  (require racket/gui/base)
  
  (define frame
    (new frame%
      (label "Example")
      (min-width 200)
      (min-height 200)))
  (xdef frame frame)
  (xdef dynamic-send dynamic-send)
Now from the Arc REPL, you can run this command:

  (dynamic-send frame 'show #t)
Since 'dynamic-send is provided by the racket/class module, doing 'xdef with libraries should work.

Some notes:

If ac.scm used the racket module instead of the mzscheme module, it would have access to all the racket/class bindings to begin with, and then I suppose I'd use a different example. ^_^

In Arc 3.1, the GUI that appears is unresponsive for me. If I Ctrl-C once in the REPL, the REPL stops processing input but the GUI becomes responsive. If I do it again, the GUI closes. I fumbled with threads trying to make the REPL and the GUI work concurrently, but nothing worked, and I've given up for now.

In Anarki, the GUI that appears is unresponsive, but doing Ctrl-C in the REPL exits Racket entirely, including the GUI. Again, my attempts to use threads haven't helped.

-----

More