simonb


9 points by simonb over 2 years ago | link | parent | top
cached 13 days ago
To me blanking is expressed most naturally as nil.

6 points by simonb over 2 years ago | link
cached 13 days ago

5 points by simonb over 2 years ago | link | top
cached 23 days ago
From another thread:

  (def strip (lst str)
    (rem [some _ lst] str))
  
  arc> (strip "abc" "aghbcdt")
  "ghdt"
  arc> (strip "" "aghbcdt")
  "aghbcdt"
  arc> (strip () "aghbcdt")
  "aghbcdt"
  arc> (strip '(#\a #\t) "aghbcdt")
  "ghbcd"

5 points by simonb over 2 years ago | link | top
cached 13 days ago
Replacing apply with @ is a great idea.

I am not so sure about unifying . and @ though. I would say . is the inverse of @. One splices the other appends [a tail].


5 points by simonb over 2 years ago | link
cached 12 days ago

4 points by simonb over 2 years ago | link | parent | top
cached 12 days ago
A somewhat messy attempt at mimicking CL's reduce:

  (let init-default (uniq)      
    (def reduce (f xs (o init init-default))
      ((afn (xs) 
         (if (cddr xs) (self (cons (f (car xs) (cadr xs)) (cddr xs)))
             (cdr xs) (apply f xs)
             xs (car xs)
             (f)))
       (if (is init init-default) xs (cons init xs)))))
For reference:

"In the normal case, the result of reduce is the combined result of function's being applied to successive pairs of elements of sequence. If the subsequence contains exactly one element and no initial-value is given, then that element is returned and function is not called. If the subsequence is empty and an initial-value is given, then the initial-value is returned and function is not called. If the subsequence is empty and no initial-value is given, then the function is called with zero arguments, and reduce returns whatever function does. This is the only case where the function is called with other than two arguments."

http://www.lispworks.com/documentation/HyperSpec/Body/f_redu...


4 points by simonb about 1 year ago | link | top
cached 10 days ago
The problem with your definition of fold is, it's not tail-recursive, which makes it less then ideal for implementing other general utility functions.

Also, to implement map you either need a right-fold or reverse the results.


4 points by simonb over 2 years ago | link | top
cached 2 days ago
Since what let does is create a closure, it will swallow anything a lambda-list will. You can for instance use optional arguments:

  (let (foo baz (o bar 3)) '(1 2)
    (+ foo baz bar))
This also means you can't bind symbol "o" to the first value of a list being destructured:

  (let (foo baz (o bar)) '(1 2 (3 4))
    (+ foo baz bar o))
  Error: "reference to undefined identifier: _o"

3 points by simonb over 2 years ago | link | parent | top
cached 13 days ago
To make it perfectly clear, I am not advocating Scheme's implementation of hygienic macros. I am merely pointing out with-gensyms is such a common pattern it would make sense to abstracted it away. Furthermore we already have such an abstraction, it is called hygienic macros.

In a language where commonly used names are abbreviated to save a character or two, "one more line" of boiler-plate should not be accepted at face value.

Ideally hygienic macros would look exactly the same as unhygienic with some clever transformations behind the scenes. For instance instead of

  (mac complement (f)
    (let g (uniq)
      `(fn ,g (no (apply ,f ,g)))))
one would write:

  (hmac complement (f)
    `(fn g (no (apply ,f g)))))
and macro hmac would do the rest (probably arriving at something resembling the former).

3 points by simonb about 1 year ago | link | parent | top
cached 10 days ago
This doesn't change the fact that your definition of fold blows the stack for large inputs.

P.S. the "you need right-fold" bit was obviously a brain-fart on my part, sorry.