Arc Forumnew | comments | leaders | submit | nex3's commentslogin

What about =? This would make a lot of sense for optional parameters with defaults, because it signifies assigning to the parameter if it's not given.

Granted, it would make less sense for just-plain-optional params, but it would be easier to visually pick out of the param list than o.

-----

4 points by nex3 6653 days ago | link | parent | on: Reference parameters

Lisps pass some objects (lists, hash tables) by reference, but others (integers, symbols) by value. In languages that offer it like C++, explicit pass-by-reference is useful because A) these languages don't deal with objects as references by default and B) to pass extra information to the caller of the function (e.g. having a boolean reference that's set to true if some condition is met).

However, A is a non-issue in Lisps and B is trivially solvable by returning a pair, so I don't see how pass-by-reference could be useful.

-----

2 points by rkts 6653 days ago | link

Consider deleting a node from a binary tree. You want a function that looks at a node and, if it's a match, unlinks it from its parent. Passing by reference allows you to do this cleanly. The alternative is to peek ahead at each subnode (messy) or to pass information up the call stack (inefficient, as the function can no longer be tail-recursive).

I'm not advocating C++ references, which I think are too implicit. If a function call foo(x) can change the value of x, there needs to be some visual indication of this. I'd prefer something like plain C pointers, with which you can pass the address of an object: foo(&x).

Of course an alternative is store objects wrapped in containers, and this isn't too bad a solution.

  (def ref (x) (obj contents x))
  (mac deref (x) `(,x 'contents))
But of course this is inefficient. If anything, this argues for adding arrays to Arc.

-----

1 point by EliAndrewC 6652 days ago | link

> However, A is a non-issue in Lisps and B is trivially solvable by returning a pair, so I don't see how pass-by-reference could be useful.

Is there an Arc equivalent to Common Lisp's multiple-value-bind macro? Because it's very awkward to have to say

    (let values (f x)
        (with (a (values 0)
               b (values 1))
            (whatever ....

-----

3 points by rkts 6652 days ago | link

Yes:

  (let (a b) (f x) ...)
although technically this is a destructuring-bind, not a multiple-value-bind.

-----


It would be really nice if this could be built into the standard def. Not with this syntax, naturally, but perhaps detecting if any pattern-like parameters showed up:

  (def factorial (0) 1)
  (def factorial (1) 1)
  (def factorial (n) (* n (factorial (- n 1))))

  (def pair ((x . y . zs)) `((,x ,y) ,@(pair zs)))
  (def pair ((x)) (list x))
  (def pair (nil) nil)
Although now that I look at it,

  (defpat factorial
    (0) 1
    (1) 1
    (n) (* n (factorial (- n 1))))

  (defpat pair
    ((x . y . zs)) `((,x ,y) ,@(pair zs))
    ((x)) (list x)
    (nil) nil)
Is more concise.

-----

1 point by almkglor 6653 days ago | link

Some nitpicks - (x . y . zs) should be (x y . zs) - note that this was buggy at the time you wrote your post, but I have just posted a bugfix on your arc-wiki.git. Also, the builtin pair uses (list (list (car xs))) for the ((x)) case.

Also, the definition of factorial above will crash on (factorial -1) but then so does Haskell if you defined it like that ^^.

-----

2 points by eds 6653 days ago | link

Is (x . y . zs) a valid list? Shouldn't it be (x y . zs)? Not that it really changes anything above... I just wanted to point it out.

-----

2 points by sjs 6651 days ago | link

If you think of the . here as Haskell's cons (:) then it makes sense. All the same, (x y . zs) can mean the exact same thing, not to mention it is shorter and familiar.

-----

2 points by almkglor 6651 days ago | link

Weird....

  arc> '(x . y . z)
  (y x z)

-----

5 points by soegaard 6649 days ago | link

Arc uses the PLT Scheme reader. The PLT Scheme reader has a non-standard (as compared to RnRS) extension, namely the double-dot notation. The double-dot notation is used to write "infix expressions".

Consider:

  (x . < . y)  is turned into  (< x y)
  (integer? boolean? . -> . void?) is turned into (-> integer? boolean? void?)
This reader extension can be turned off, but setting the appropriate parameter.

-----

1 point by sjs 6650 days ago | link

That is strange, and probably a bug. You can use up to 2 dots and the last dot is handled first, consing x and (z . nil) then consing y and (x (z . nil)). '(w x . y . z) gives (y w x z).

I can almost see how this bug appeared. Searching for the first part of a dotted expression yields (w x), and then searching for the 2nd part yields z. For some reason the expression becomes '(y . (w x z)); that I cannot explain without looking at the code.

-----

2 points by nex3 6656 days ago | link | parent | on: Poll: What would you change in Arc?

The way I solved this in the Wiki was to give tagged values (except macros) the same calling semantics as their non-tagged equivalents. Thus, you can represent arbitrary datatypes as functions, tagging them to keep track of their type but still calling them.

-----

4 points by vincenz 6656 days ago | link

That's completely the opposite of what I want :)

I want:

    a) The ability to define within arc what happens when a list is 
         used as function, instead of it being predefined in scheme
    b) The ability to do this for any type and custom types.
 
And potentially:

    c) For annotated values to be able to do this per-object, 
        by storing an extra field in there that is the getter, 
        where the default value is the one for the type.

    E.g:  (annotate 'blabla value getter)
If there is no getter, then use the one for type 'blabla

-----

1 point by nex3 6656 days ago | link | parent | on: Can Arc run as a script instead of REPL?

At the moment, I don't believe this is possible.

-----

3 points by nex3 6656 days ago | link | parent | on: Indexed data structure support?

defset does just that.

-----

1 point by jimbokun 6656 days ago | link

Thanks for the tip!

-----

4 points by nex3 6656 days ago | link | parent | on: Bug in hash tables ?

It looks like an issue with Scheme, rather than Arc. Check out the following Scheme session:

  > (define t (make-hash-table 'equal))
  > (hash-table-put! t t 'foo)
  > t
  #0=#hash((#0# . foo))
  > (hash-table-get t t)
  ; Loops forever

-----

3 points by soegaard 6656 days ago | link

"Issue". It behaves as specified. From R5RS:

Equal? recursively compares the contents of pairs, vectors, and strings, applying eqv? on other objects such as numbers and symbols. A rule of thumb is that objects are generally equal? if they print the same. Equal? may fail to terminate if its arguments are circular data structures.

There is a silver lining though. In R6RS the following was added:

  Note: The equal? procedure must always terminate, even if its arguments contain cycles.

That is, there is a good chance that the behaviour of equal? changes, when the PLT Scheme team begins implementing the R6RS language.

-----

1 point by sacado 6656 days ago | link

I submitted a bug report to PLT Scheme about that. Here's their answer :

"The process for generating an `equal?' hash key is defined to not terminate on circular objects, such as a hash table that contains itself. So `(hash-table-get <any-table> t)' loops trying to generate a key for `t'.

The specification of hashing has changed for the next release to deal gracefully with cyclic data, just as `equal?' has changed so that it can compare cyclic data. In the current pre-release version, v3.99.0.10, your example returns immediately.

(It returns with a "key not found" error. That's because the process of installing a hash table into itself changes the table's own `equal?' hash key.)"

-----

4 points by nex3 6656 days ago | link | parent | on: aif bug and fix

By all means commit this to the repo. The idea of a wiki is "push first, ask questions later." It's by no means critical that the wiki stay stable; that's what git://nex-3.com/arc.git is for.

-----

4 points by nex3 6656 days ago | link | parent | on: User defined symbol parsing or symbol macros

I like the idea, although I'm not sure what your syntax is. All those ^s and $s start making it look like line noise.

Since we'd need to have a predefined set of "definable" operators anyway, why not just make the syntax as follows?

  (symac target.message
    `(send ,target ',message))

  (symac start..end `(range ,start ,end))

-----

8 points by nex3 6657 days ago | link | parent | on: Arc Repo

Git makes a distinction between your local repository and remote repositories. You have to commit your change to your local repo before you can push it to the remote one. So first you "git commit," then you "git push."

The total workflow goes something like this:

  git clone git://nex-3.com/arc-wiki.git
  emacs lib/import.arc   # Make your edits
  git add lib/import.arc # Schedule lib/import.arc for committing
  git commit             # Commit lib/import.arc to your local repo
  git push               # Push your local changes to the remote repo
The "git add" step is due to a little idiosyncrasy of Git where "commit" doesn't commit any changes you don't explicitly tell it to via "git add." You can also do "git commit -a" to automatically add all changes before you commit.

Also, "git commit" takes the same -m parameter that "svn commit" does.

Finally, the GNU Smalltalk folks have a good intro to Git: http://smalltalk.gnu.org/blog/bonzinip/using-git-without-fee....

-----

1 point by randallsquared 6657 days ago | link

Thank you; that was exactly what I needed. :)

-----

1 point by treeform 6635 days ago | link

i hope pg commits to it too

-----

More