Arc Forumnew | comments | leaders | submit | nostrademons's commentslogin
5 points by nostrademons 6269 days ago | link | parent | on: Arc Ported to JavaScript

What's a good repository to park the source in? I don't really plan on maintaining this, but want to offer it up for community hacking. Heard there's a git repository floating around, but I'm a total git newbie...

-----

3 points by vincenz 6269 days ago | link

For the repo, check this: http://arclanguage.com/item?id=809

-----

2 points by nostrademons 6269 days ago | link

I keep getting "fatal: sha1 file '<stdout>' write error (Bad file descriptor)" when I try to git-push to the wiki repository, so if someone for whom git works wants to grab the tarball and import it, feel free.

-----

2 points by nostrademons 6270 days ago | link | parent | on: how exactly does a:b work?

It's because the ~: syntax is expanded at evaluation time, not at read-time. The Arc compiler looks at each symbol, and if it has one of those characters, it splits on the :, wraps in (compose ...), and adds a (complement ...) form every time the section begins with ~.

-----

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

I really like #4, but what other data types would it support? Arc doesn't currently have anything other than lists, hashtables, and primitives. Unless you mean specifying call and set operations for tagged data types...

-----

3 points by vincenz 6270 days ago | link

You can define any type you want with 'annotate'.

For instance, if you look at arc.arc, you'll see the first two macros are defined without the use of the macro mac. Using

   (set foo (annotate 'mac some-function))
This sets the type to a 'mac (or macro :)

So yes, I guess I do mean for tagged data-types, but also for any possible future 'native' types that it will come to support. Or even redefining it within the context of your application.

-----

2 points by nex3 6270 days ago | link

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 6270 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

-----


Honestly, do you really expect Yahoo is going to go after a bunch of hobbyists using a toy language?

-----

2 points by randallsquared 6271 days ago | link

If they choose not to, do they lose the right to claim damages later, as with trademarks?

-----


What happens if you need to scale to multiple servers? Or if the server goes down for a reboot?

-----

5 points by pg 6273 days ago | link

You'd do the same sorts of things you'd do in any language.

-----

6 points by nostrademons 6273 days ago | link

In other languages, you'd typically store the session in memcached or the database, and then run multiple web frontends that each connect to the shared memcache instance or DB server. Can you serialize closures and store them in an external backend, assuming the existence of memcached and/or database bindings?

(I'm not asking this to prove a point or be a dick...this is a real issue in a lot of deployments. Java/JSF takes the same approach - it stores the complete state of the user interaction in a tree on the server, and then uses either a cookie or URL parameter to retrieve that state. A coworker and I spent a couple weeks digging into the JSF internals to get it to operate statelessly; the base JSF framework worked fine with a configuration change, but the AJAX framework built on top of it choked miserably.)

-----

1 point by dc27437 6271 days ago | link

What did you do to get the base JSF to work on multiple servers? I am having that issue now - whenever a server switch is done, the context set up by JSF is lost and a blank page shows. Results 2 thru n on the same server are fine, result 1 being the initial page (JSP) request. Thanks.

-----

1 point by nostrademons 6271 days ago | link

For basic JSF, you just set a context-param on your web.xml for javax.faces.STATE_SAVING_METHOD = client.

http://forum.java.sun.com/thread.jspa?threadID=594475&me...

It'll serialize the UIComponent tree and store it in a hidden input field with every interaction, then restore the view from that field. Naturally, this doesn't work if you're using GET for forms. (There's an undocumented feature of JSF where you can change the form method using JavaScript and make it submit information via GET. It tends to break though - you can easily overflow query strings, and I recall some problems when binding components to bean properties.)

-----

1 point by dc27437 6270 days ago | link

Thanks! I appreciate it.

-----

5 points by nostrademons 6273 days ago | link | parent | on: Take the Arc Challenge

Reddit clone, including AJAX voting & comments and different sort orders.

-----

5 points by emmett 6273 days ago | link

Wait a second...I think we might already have this written in Arc...

-----

1 point by nostrademons 6273 days ago | link

I think we might already have it written in several languages...

So let's have the Reddit-clone challenge!

-----

5 points by nostrademons 6273 days ago | link | parent | on: Is Arc good for big projects?

Hahahaha no. Lisp-1 + unhygienic macros + no module system = a world of pain when projects grow beyond a few thousand lines, even ignoring the lack of user-defined data types. The lack of structured data is less of a problem than it might seem, because you can write accessor functions that abstract away whether it's stored in a list or hashtable and the precise keys, and just use those. The issue is namespace-pollution from all those accessors.

I'd kinda like to see Arc grow some sort of module system - even a very simple dictionary-based system like Python's or JavaScript can go a long way towards making larger programs tractable. Come to think of it, I think you could emulate JavaScript's system with closures and hashtables. Just wrap every module in a closure, which binds a hashtable to the module name and inserts each function into the hash table:

  ([do
   (set My-Module-Name (table))
   (= (My-Module-Name 'foo) (fn (arg1 arg2) ...))
   (= (My-Module-Name 'bar) (fn (arg) ...))
   (= (My-Module-Name 'baz) (fn () ...))
  ] 'ignored)
A little macrology could make this a bit more elegant:

  (module My-Module-Name
     (private my-private-method (arg1 arg2) ...)
     (public my-public-method (arg1 arg2) ...)
     (public my-other-method (arg1) ...))
The macro code would look something like this:

  (mac module (name . spec)
    (with (car-is (fn (sym) [is sym (car _)])
           public-forms (keep (car-is 'public) spec)
           private-forms (keep (car-is 'private) spec)
           make-public [`(= (,name ,'(cadr _)) (fn ,@(cddr _))]
           make-private [`(,(cadr _) (fn ,@(cddr _)))])
      `([(do
          (set ,name (table))
          (with ,(mappend make-private private-forms)
             ,@(map make-public public-forms)))] 'ignored))
Now I kinda want to install MzScheme and try it out...I've been working off the tarball source only. :-)

-----

4 points by chandler 6272 days ago | link

As far as I can tell, having a purely closure-based module system won't actually solve the lisp-1 redefinition problem; to use your module system, some manner of compile-time token capture is necessary. Essentially, the problem is:

  (= my-module
     (let obj (table)
       (= (obj 'rem-xs) (fn (s) (rem #\x s)))
       ...
       obj))

  ((my-module 'rem-xs) "abcxdefxghi") ;; => "abcdefghi"
Now, suppose I redefine "rem" at the toplevel to be like the BASIC rem, or a remark function that ignores its parameters:

  (def rem args
    nil)

  ((my-module 'rem-xs) "abcxdefxghi") ;; => nil
I think Arc uses a lexical scope, so this problem shouldn't show up in the following example:

  (aload 'my-module)

  (let rem (fn args nil)
    ((my-module 'rem-xs) "abcxdefxghi"))

  ;; => "abcdefghi"
However, you would need to be careful when attempting some kind of dynamic import:

  (let rem (fn args nil)
    (aload 'my-module)
    ((my-module 'rem-xs) "abdxdefxghi"))

  ;; => nil
I think the former (though not latter) problem can be mitigated by shadowing all functions/globals you want to stay invariate, as in:

  (= my-module
     (with (rem rem
            table table
            fn fn
            obj (table))
       (= (obj 'rem-xs) (fn (s) (rem #\x s)))
       ...
       obj))

  ((my-module 'rem-xs) "abcxdefxghi") ;; => "abcdefghi"
However, as you can imagine, this will get unwieldy fairly quickly (like you, I've downloaded the arc0.tar file, but not actually bothered to downgrade my copy of plt-372; i.e., I'm not sure how canonical the provided arc snippets are).

Of course the ignored caveat is this: so many bloggers are up in arms over this point, it's presupposed that being able to change core library functions is a defacto terrible thing--at work, where we have a massive C/C++ codebase running on some unmaintained, sourceless, legacy APIs, being able to (for example) add/fix methods in some of the base classes would be a significant time-saver.

I think Arc as-is makes it a bit too easy to shoot yourself in the foot; however, I'm firmly in the camp that being able to update core functionality should be allowable.

Also, for better or worse, look at emacs: a massive, mature system that contains no module/namespace system, no closures, and, due to its dynamic scope, would fail each of the above examples. I'm not saying I hope Arc emulates these (lack of) features, however, it's still proof that they're not necessary for large, real-world (whatever that means) projects.

-----

3 points by cpfr 6272 days ago | link

The big problem is def and =s update a global symbol table. They are not like Scheme and define. If def obeyed local scoping rules and could be shadowed, the problem is shadowing has to be done explicitly. That is why this is painful and unwieldy. Ultimately, this needs to be fixed or Arc will be needlessly crippled.

-----

2 points by jdvolz 6273 days ago | link

What kind of syntax should we use to denote the module? Something like:

(module::function args)

This idea comes from Ruby, though I am not sure it necessarily plays well with the function composition operator (func1:func2). I wouldn't want to use -> or "." because of the concept collisions those would create. Could we just use something that doesn't have a mainstream meaning, like (module#function) or (module>>function)?

-----

1 point by nostrademons 6273 days ago | link

module::function looks good to me. Someone else suggested allowing user-defined syntax characters; this would be a good use-case. It only has to expand into (module 'function), so the implementation is basically trivial.

-----

2 points by cpfr 6273 days ago | link

Why not module:function? Abuse the property that : stands for composition. A more lispy solution of (module function) might also work, and its only an extra character. Though if I were going for an Arc solution, it should probably be (bin fn) or (md fn).

-----

1 point by randallsquared 6271 days ago | link

In case you hadn't noticed, there's a sketch of a module system in the arc-wiki repo that does exactly this, now.

It doesn't solve the problems mentioned in this thread, of course.

-----

1 point by greatness 6273 days ago | link

This seems like it'd be closer to classes/objects than modules.

-----

2 points by nostrademons 6273 days ago | link

In JavaScript they're the same thing - objects do quintuple-duty as hashtables, records, objects, classes, and modules. Arc is very similar to JavaScript in terms of the primitive data types available - they're both Scheme-derived languages.

The reason I'd term call this modules is that they don't have the implicit-receiver that classes/objects do, nor do they have constructors. Once you define a module, that's it, and they live in the global namespace. You could change things around pretty easily so that instead of immediately executing the closure containing the module's namespace, you define it as a constructor function. And you could probably then come up with some macro to expand to a message send, which passes the object as the first argument to any method defined in it. I think you'd be stuck with explicit-self though, like in JavaScript or Python, instead of the implicit `this` of Java.

-----

3 points by mst 6273 days ago | link

... and scopes.

Javascript's scope chaining is one of my most and least favourite things about the language. But it's a damn clever approach once you get it.

-----

4 points by nostrademons 6273 days ago | link | parent | on: Unquoting

Backquote, comma, and comma-at are reader macros that expand into quasiquote, unquote, and unquote-splicing, respectively. So your example expands to

  (quasiquote (a b (unquote-splicing args) (unquote x)))
If you allow unquoting within quote, how do you tell the difference between an evaluated (unquote x) form and a literal (unquote x)? You might want the latter if, for example, you have a macro that returns another macro with unquoting.

-----

1 point by bogomipz 6273 days ago | link

Simple; '$x versus ''$x

-----


Javascript, all done client-side, using JQuery:

  $('body').append('<input id = "myInput" /><input type = "submit" />')
    .find('input[@type=submit]').click(function() {
       val = $('#myInput').val();
       $('body').html('<a href = '#'>click here</a>').find('a').click(function() {
          $('body').html('You said: ' + val);
       });
    });

-----

7 points by tlrobinson 6273 days ago | link

Without JQuery...

<input id="in" type="text" /><input type="submit" onclick="window.result='You said: '+document.getElementById('in').value; document.body.innerHTML='<a href=\'#\' onclick=\'document.body.innerHTML=window.result;\'>click here</a>'" value="Submit"/>

(it's a big hack, I know)

-----

3 points by bdeterling 6272 days ago | link

Using Prototype and even more of a hack: <script src="prototype.js"/><input id="a"/><input type="submit" onclick="h=Element.hide;h('a');h(this);u=Element.update;u('c','Click Here');"/><a id="c" onclick="u('c','You said '+$F('a'))"/>

-----

-3 points by name 5968 days ago | link

vffgf

-----

1 point by murkt 6273 days ago | link

Nice! Compare to Ruby ones :)

-----

5 points by nostrademons 6274 days ago | link | parent | on: Alphabetical List of Arc Functions

Haven't tried it, but I believe this is what the `sig` global hashtable is for. It stores a mapping of all defined functions to their signatures...

-----

1 point by parenthesis 6274 days ago | link

Yes:

  (sort (fn (x y) (< (coerce x 'string) (coerce y 'string))) (keys sig))
(As it says in the link, first comment out

  ;(aload "libs.arc")
in as.scm for just the basic arc.arc functions and macros.)

-----

4 points by hakk 6274 days ago | link

Shorter:

    (sort (compare < [coerce _ 'string]) (keys sig))

-----

4 points by fallintothis 6273 days ago | link

Shorter:

  (sort < (keys sig))
< compares symbols as it would strings.

-----

1 point by sjs 6274 days ago | link

Cool, not just functions but macros too.

-----