Arc Forumnew | comments | leaders | submitlogin
3 points by rocketnia 4785 days ago | link | parent

It took me a while to reply because I was planning to do some of my own testing before posting, but I haven't found the time.

---

"You mean the "destructuring is just lambdas" thing?"

No, I don't know what to think about that yet. I like it if and only if this works:

  (let (a . b) '(1 . 2)
    ...)
Even if that works, I almost expect Racket to copy a mutable argument list into an immutable one for use inside the lambda, so here's a second test case:

  (withs (foo (list 1 2 3)
          (a . b) foo)
    (= b.0 4)
    (is foo.1 4))
What I definitely do like is the use of Racket's optional arg syntax where possible. ^_^

---

"It would seem Racket optimizes lambdas very heavily."

IMO, those examples aren't normal uses of (define ...), since they're contexts where the variable is already defined. I'd like to test these cases:

  ; Racket code
  
  (let ((a 5)) a)
  ((lambda (a) a) 5)
  (begin (define a 5) a)
    ; NOTE: Make sure this (begin ...) isn't at the top level, or the
    ; definition will be global.
  (let () (define a 5) a)
  ((lambda () (define a 5) a))
One reason it's on my mind is the Racket 5.2 changelog (http://lists.racket-lang.org/users/archive/2011-November/048...):

  * Internal-definition expansion has changed to use `let*' semantics
    for sequences that contain no back references.  This change
    removes a performance penalty for using internal definitions
    instead of `let' in common cases, and it only changes the meaning
    of programs that capture continuations in internal definitions.
    Internal definitions are now considered preferable in style to
    `let'.
Then again, if they're going to make more semantic changes like this one, it might be better to avoid compiling to an internal-definition style. :-p

Anyway, from the phrasing in the changelog, it sounds like internal definitions are implemented in ways the programmer can already control at a lower level with things like 'let*, so you'll probably continue to find that internal definitions are at least as slow as other options.



2 points by Pauan 4785 days ago | link

"I like it if and only if this works:"

That doesn't, but this does:

  (let (a . b) '(1 2 3)
    ...)
The reason is because racket-mlist->list expects a proper list. I can fix that easily.

Update: I fixed racket-mlist->list, but Racket's apply absolutely positively requires a proper list, so it looks like I can't use nested lambdas if I want to fix that: I'll have to use a Racket let*

---

"I almost expect Racket to copy a mutable argument list into an immutable one for use inside the lambda"

It's true, it does copy the list, so that returns nil. I wonder if I can work around that...

---

"One reason it's on my mind is the Racket 5.2 changelog"

I'm not using Racket 5.2. And even if I were, the reason for the speed tests was to see how it would perform within the (fn ...) expansion, where it does indeed overwrite an already-existing variable. (Though I could change it to use a gensym...)

-----