Arc Forumnew | comments | leaders | submit | bogomipz's commentslogin
2 points by bogomipz 6473 days ago | link | parent | on: Forum Search?

A form that redirects to google should be easy to implement. Another simple approach, that you can do for yourself, is to add a quick search in Firefox. I have this bound to keyword 'a';

http://www.google.com/search?q=site:arclanguage.org+%s

The problem with using google to search forums, however, is that it doesn't know anything about threads. When I type 'a module' in FF's location bar, I get 121 hits (should be 122 after I post this ;), and I have no idea how many threads that is - not very practical.

-----

2 points by bogomipz 6478 days ago | link | parent | on: Hygienic Macros

A problem with unquoting the function value is that if you redefine the function, any code that uses the macro will hold on to the original function as a literal. This means the solution doesn't lend itself well to exploratory programming.

-----

2 points by raymyers 6478 days ago | link

Yes, it is true that preventing redefinition will in fact prevent redefinition. Bear that in mind when preventing redefinition :)

-----

1 point by bogomipz 6478 days ago | link

Well, one could create a module system so that the macro would always see the function the way it was seen in the module where the macro was defined. Then, when the function name is rebound where the macro is applied, it doesn't affect the macro, but if the function is recompiled in its original module, it does affect the code produced by the macro. I'm not saying it's straight forward, but I do believe it's possible.

-----

2 points by bogomipz 6480 days ago | link | parent | on: Score one for Arc

I'm sure you will remember to use foo:bar when the alternative is (fn args (foo (apply bar args)))

Using : only in the most important places might be a good thing. I.e not overuse it for (foo (bar x)) -> (foo:bar x) where it trades readability for 2 characters.

-----

3 points by bogomipz 6480 days ago | link | parent | on: Implicit progn

Just a follow up question on this. How do people feel about (fn ... ) not having implicit progn? That sounds extreme, I know, but it would open the door for pattern matching in the very core of Arc.

  (fn (x y)
        (prs "two args:" x y)
      ((x . xs))
        (prs "a cons cell:" x xs)
      args
        (prs "many, many args:" args))

-----

1 point by drcode 6480 days ago | link

that actually looks pretty nice...

-----

2 points by bogomipz 6485 days ago | link | parent | on: Ruby-like in place list expansion

The more I think about this, the more mind boggling I find it. What exactly would this expression expand to?

  (and (acons x) (car x) @lst)
The actual lst is only available at runtime, while the 'and macro expands at compile time.

  Edit:
After looking at the definition of 'and, it is clear that the above could never work. Without performing the splice it would expand to

  (if (acons x) (if (car x) @lst))
For each additional argument 'and must add another 'if to the code, so with lst being spliced in at runtime, we have an impossible problem.

It seems @ can only ever work reliably in quasiquote. I guess longtime lispers already knew, otherwise we would probably have had this feature for several decades already.

If you insist, it could still be done for functions. To avoid inefficient code, it better be smart about how it builds the list;

  (foo 'a @lst)     -> (apply foo (cons 'a lst))
  (foo 'a 'b @lst)  -> (apply foo (append (list 'a 'b) lst))
  (foo @lst 'c 'd)  -> (apply foo (append lst (list 'c 'd)))
  (foo @lst 4 @bar) -> (apply foo (append lst (cons 4 bar)))
and so on.

-----

1 point by absz 6482 days ago | link

I had assumed that (and (acons x) (car x) @lst) would expand to (and (acons x) (car x) lst.0 lst.1 ... lst.N), and only then would it expand to (if (acons x) (if (car x) (if lst.0 ...))). In other words, @s are expanded as though they were the outermost macro, not the innermost. That should remove the problem of 'and having to be psychic. Your point about efficiency, however, is a very good one.

-----

2 points by bogomipz 6480 days ago | link

As mentioned, the macro expands at compile time, but the value of lst is not available until runtime.

In order to expand a call to 'and with 6 sub expressions into (if e0 (if e1 (if e2 (if e3 (if e4 e5))))), all 6 expressions must be visible at compile time.

Splicing in a list of arguments to a macro will simply never work (except by compiling the code from scratch each time you run it, i.e. limiting yourself to the most inefficient of interpreter techniques)

-----

1 point by absz 6480 days ago | link

Aha! Oh, I see. I should have realized that. Yes, that's a problem :) I'm not convinced it's insurmountable, but this syntax certainly won't work. Thank you.

I still, however, think it might be nice for functions, but that's merely a difference in appearance, not functionality.

-----

1 point by bogomipz 6485 days ago | link | parent | on: Ruby-like in place list expansion

That means (+ . (1 2 3)) does what you want, doesn't it?

Granted, to do the equivalent of (+ @(foo)) you would have to do;

  (let temp (foo)
       (+ . temp))
Which is not very nice at all, so I'm not arguing against @. On the contrary.

Edit: I used to think that . and @ would only differ in the sense that cons and splice have different list building semantics, but now I believe that they should also differ in the timing of the operation;

  (+ . (foo))  -> (+ foo)
  (+ . '(foo)) -> (+ quote foo)
  (+ @(foo))   -> what we want, given that foo returns a list
  (+ @'(foo))  -> (+ 'foo)

-----

6 points by bogomipz 6485 days ago | link | parent | on: More generic if macro

You could use this, though;

  (if (~expr1)
        (...)
      (~expr2)
        (...))

-----

1 point by raymyers 6485 days ago | link

True, though that only works for function calls -- not variables: (if (no li) ...)

-----

10 points by bogomipz 6485 days ago | link | parent | on: Syntax for optional/keyword args

Keyword arguments definitely have their place. They fix a problem with having too many optional args. Example:

  (def foo (a b c (o d) (o e) (o f) (o g))
If you want to call foo with g but not the other optional args, you'd have to write

  (foo 1 2 3 nil nil nil 42)
It's easy to loose track of positional args when there are more than say 5 of them (depends on the person), and it gets a lot worse when some are just nils. The above call with keyword args instead of optionals would be something like;

  (foo 1 2 3 'g 42)
Or, depending on the implementation, there might be a special syntax;

  (foo 1 2 3 :g 42)

-----

3 points by aston 6485 days ago | link

I think there are two distinct cases here. The first is when a procedure is taking a number of options/switches. The second is when the function has a long list of optional arguments.

I actually think the second is pretty rare, especially if the argument list is ordered by practical use. The first is handled pretty nicely by passing in association lists or hash tables. Of course, the current syntax for creating hash tables doesn't make using them as arguments super-easy, but they're the equivalent of passing a dictionary in python for kwargs, and they don't require any new syntax.

edit: In my imagined world, your last example would look something like

  (foo 1 2 3 (table g 42))
where table could take kv's ad infinitum.

-----

2 points by bogomipz 6485 days ago | link

I don't see the distinction between taking a number of options and having a number of optional arguments. To me, this is exactly the same. A switch is an argument that is only checked for true/false, which means that in ordinary function calls you only really want to bother with it when passing 't.

It's true that passing a data structure can do most of the job of keyword arguments. Any searchable structure will do, really. Perhaps the simplest form from the call site's point of view is a property list. If Scheme's plist-get was implemented in Arc (trivial, but pg would probably pick a shorter name):

  (def foo (a b c . rest)
    (plist-get rest 'g))

  arc> (foo 1 2 3 'g 42)
  42
So, what do keyword arguments give you that tables/alists/plists do not?

1) better self documentation - the function signature tells what keys it understands

2) less code in the function body - you access the value like any other argument

3) a default form which is only evaluated if no value was given - without adding code to the function body

-----

1 point by sjs 6485 days ago | link

How about something like this:

  (def kw args
    (listtab (pair args)))
That makes it pretty easy to pass around kw args, and with a macro you could make it a little more sugary by allowing unquoted keys.

-----

2 points by bogomipz 6486 days ago | link | parent | on: Reflection in arc?

When you say environment, do you mean lexical environment or global namespace? Neither is possible today, I believe, but when someoneā„¢ writes a module system for Arc, namespaces will hopefully be right at your finger tips (if implemented as Arc tables).

-----

4 points by bogomipz 6486 days ago | link | parent | on: Regexp name definition

Problem is, you're adding a coupling between the function and the name. No such coupling exists in any lisp that I'm aware of. Conceptually, in Scheme and Arc

  (def foo (x) (prn "it's " x))
is the same as

  (= foo (fn (x) (prn "it's " x)))
i.e. all functions are anonymous from their own pov.

Also, variable lookup is going to be very slow. What you're saying is that the following will make lookup of any name starting with "a" return the same value;

  (= /a.*/ 42)
I'm sure lots of interesting tricks can be done with this, but I'm afraid it adds a lot of complexity only to make very confusing functions possible.

-----

1 point by bramsundar 6485 days ago | link

I think that there are some nice possibilities lurking in this idea. Perhaps there could be a macro defined that modifies def to use this functionality (kind of like pm:def).

-----

2 points by bogomipz 6485 days ago | link

You can't make a macro create an infinite set of global bindings.

-----

More