Arc Forumnew | comments | leaders | submit | evanrmurphy's commentslogin
3 points by evanrmurphy 5552 days ago | link | parent | on: html.arc: another approach

I'm quite impressed, actually! In addition to the name (which in itself beats my (html (html problem), the quoting system seems smart. I'm going to have to mull this over more.

Another punctuation possibility I've considered that's different from both of these is quasi-quotation,

  (tohtml     ; another decent name
    `(body
      (h1 "Simple Math")
      (p "1 plus 1 equals " ,(+ 1 1))

  ; would generate:
  ; <body><h1>Simple Math</h1><p>1 plus 1 equals 2</p></body>nil

which would seem like a very natural way to escape into Arc. Not only does it look better, but it could get me out of using 'eval in that 'htmlf function. In fact, the more I write about this, the better it sounds. I think I'll give quasi-quotation a shot.

-----

3 points by shader 5552 days ago | link

I think that

  `(body
    (h1 "Simple Math")
    (p "1 plus 1 equals " ,(+ 1 1))
and

  ('body
    ('h1 "Simple Math")
    ('p "1 plus 1 equals " (+ 1 1))
are probably equivalent, though I don't know how quoting affects strings. Odds are the same system could handle both styles, which means that programmers could use whichever they prefer. Personally I like the 'tag notation for tags, but hopefully it would be flexible enough to handle both.

What's the current status of whtml.arc? I can't look at the repo right now. Does it look like something that could be used as is?

-----

1 point by evanrmurphy 5552 days ago | link

> probably equivalent

I agree that they seem close and are probably one macro apart from behaving the same, but they must be different since the latter throws

  Error: "Can't coerce  body fn"
while the former returns a list. I think its equivalent normal-quoted expression would have to be something more like:

  (list 'body
    (list 'h1 "Simple Math")
    (list 'p "1 plus 1 equals " (+ 1 1)))
I haven't found whtml at http://github.com/nex3/arc/tree/master/lib/ yet. I did however just stumble upon sml.arc by akkartik, which appears to be super relevant to this discussion.

-----

1 point by shader 5552 days ago | link

It looks like sml supports both '@ based attributes and also a form like

  (tag attr1 "value" attr2 "value"
    (bodyless-tag)
    (tag-w/body "body"))
It looks like it's function based and works on simple lists, so it would probably be conducive to the quasiquote form of escaping to arc. Anything seem to be missing from sml.arc that you wanted in your new version? Personally I think the interface could use some work, but that's about it.

-----

1 point by shader 5552 days ago | link

Hmm. I'll have to see if I can find it elsewhere. I guess that w/html must have been a macro that bent quotes to its own purpose, whereas marcup or your 'tohtml merely take lists as input.

sml.arc sounds familiar; I vaguely remember someone else going through a discussion similar to ours, in which SXML was also mentioned.

-----

1 point by akkartik 5535 days ago | link

I shouldn't get any credit for jazzdev's sml.arc: http://github.com/nex3/arc/commits/master/lib/sml.arc

-----

1 point by evanrmurphy 5533 days ago | link

Thanks for clarifying the authorship.

-----

2 points by evanrmurphy 5552 days ago | link | parent | on: html.arc: another approach

Thanks for the link and feedback.

> Also, why are some of your expressions wrapped in an extra layer of parens? i.e. ((script src "arc.js")). Is this so that you can differentiate the body vs attributes?

Yes, exactly. I can see now that they're using the @ symbol to differentiate attribute lists, but it's interesting to note that they actually end up using more parens. Unless I've misunderstood, where my program would have

  ((a href "http://arclanguage.org" onclick "alert();") "click here")
SXML would have

  (x:a (@ (href "http://arclanguage.org") (onclick "alert();")) "click here")
In light of this, could you elaborate on your recommendation to adopt SXML's syntax? Do you find it somehow superior or does it have more to do with adopting a standard?

> For the (html (html issue, I would consider instead making a more general 'sxml macro, and then several helper macros such as 'html which automatically generate boilerplate doctypes, etc.

Sounds like a wise path of generalization to carry out over the long run.

-----

1 point by shader 5552 days ago | link

You're right, I hadn't noticed how many parens SXML actually uses. I guess I just preferred more of a tree style "tag owns attributes" than the idea of applying a tag to its body.

I originally like the idea of the standard, but SXML probably supports far more than we need for now. How about a compromise?

  (x:a (@ href "http://arclanguage.org" onclick "alert();") "click here")
This uses arc's style of "leave out parens for grouping pairs" like you were doing, but also doesn't require the attribute parens if you don't have attributes. This seems to make the tag style more homogeneous.

-----

3 points by rocketnia 5552 days ago | link

Why use parentheses at all?

  (x:a href "http://arclanguage.org onclick "alert();"
    "click here")
The body can be distinguished from the attribute-value pairs thanks to either the fact that it doesn't begin with a symbol or the fact that there's nothing to pair it with.

-----

2 points by evanrmurphy 5552 days ago | link

Wow, neat idea! I'm looking into it right now...

And Arc continues on its quest to become the most parens-frugal Lisp there ever was. :P

Question: Do y'all like the x:a? It seems kludgy to me and I'd rather just do a, but maybe I'm missing the point...

-----

2 points by rocketnia 5551 days ago | link

Wow, neat idea! I'm looking into it right now...

Oh, I guess sml.arc already allows for that syntax. XD I should have taken a closer look....

Anyway, in case it helps, Lathe has a utility called parse-magic-withlike defined here: http://github.com/rocketnia/lathe/blob/master/arc/modules/mo...

It does save a single pair of parentheses every once in a while, but it takes half a page of comments to explain comprehensively. :-p Then again, it's meant for Arc macros in general, so some of the idiosyncracies might disappear if it's modified for a specific purpose like this one.

Do y'all like the x:a?

I thought the "x:a" was just an abbreviation for things like "w/html:a", "html:a", "tohtml:a", and "sml:a", substituting whatever you decided the macro name would be. What alternative are you thinking about?

-----

2 points by evanrmurphy 5551 days ago | link

> I thought the "x:a" was just an abbreviation for things like "w/html:a", "html:a", "tohtml:a", and "sml:a", substituting whatever you decided the macro name would be.

The "x:a" originally came from the example at http://en.wikipedia.org/wiki/SXML#Example, where I think it had another meaning - maybe something to do with XHTML... anyway, it's probably not important. You clarified that I wasn't missing something in the conversation (unless we both are ;).

-----

2 points by shader 5551 days ago | link

I think in the x:a syntax, the x part is supposed to denote the xml namespace in which the tag is defined. It's used in things like xpath.

-----

1 point by rocketnia 5551 days ago | link

I think so too. The x is defined here at the beginning of the example:

  (*TOP* (@ (*NAMESPACES* (x "http://www.w3.org/1999/xhtml")))
   ...
There's an okay introduction to namespace usage in XML and SXML here: http://www196.pair.com/lisovsky/xml/ns/

-----

1 point by evanrmurphy 5552 days ago | link

> This uses arc's style of "leave out parens for grouping pairs" like you were doing, but also doesn't require the attribute parens if you don't have attributes.

I like that compromise and will definitely consider it. To be sure though, my current implementation doesn't require the attribute parens for nil attributes either:

  arc> (html (h1 "Some heading"))
  <h1>Some heading</h1>
  arc> (html (script "someFunction();"))
  <script>someFunction();</script>
On these cases, my html.arc and the compromise converge. It's for the non-nil attributes case that they differ, and I think it comes down which you dislike less: the tag name in the caar position or the @ symbols.

-----

1 point by shader 5552 days ago | link

Yes, but your current method seems to lack consistency (at least to me).

In some cases, (script fn "somefn();") means script with attributes, in others it means that it has a body. The difference is where the (script ...) is located; at the car of a list or not. Personally, I like the consistency provided by "anything that's not an @ list is body" which means that you don't have to pay as much attention to the number and layering of parens.

-----

2 points by evanrmurphy 5552 days ago | link | parent | on: Suggestion: how to improve arc.

How would using ampersand over dot make macro writing much easier? Is it just that you find the notation more intuitive, or is there something else?

Personally I prefer the dot because I think it looks less jarring and there's the connection with improper lists, as pg mentions in the tutorial (http://ycombinator.com/arc/tut.txt):

  (These conventions are not as random as they seem.  The parameter
  list mirrors the form of the arguments, and a list terminated by
  something other than nil is represented as e.g. (a b . c).)

-----

2 points by ylando 5552 days ago | link

Suppose that you want to write a macro that define a function:

  (mac def-func (func-name func-body)
    (w/uniq first-arg
      (w/uniq rest-arg
         `(def ,func-name (,first-arg . ,rest-arg)
             ,@func-body))))
And it will not work. There is a problem with using dot in quasiquote.

-----

3 points by shader 5552 days ago | link

So your real question is why dots don't work in quasiquote, and what should be done to fix them. That's a question that we can relate to a lot better than what we originally thought was "I don't like dots"

-----

2 points by evanrmurphy 5552 days ago | link

Would someone mind being more explicit about how it doesn't work? After dotting the outer definition's rest parameter as well so that the first line reads,

  (mac def-func (func-name . func-body)
it seems to be working for me:

  arc> (def-func 1+1 (+ 1 1))
  #<procedure: 1+1>
  arc> (1+1 nil)
  2
If you're interested, here's a version of your macro with a few things cleaned up (some changes only subjectively better):

  (mac def-func (name . body)
    (w/uniq (first rest)
      `(def ,name (,first . ,rest)
         ,@body)))

-----

1 point by ylando 5552 days ago | link

It don't work with jarc16, it don't work with arc3. What is your version of arc?

-----

1 point by evanrmurphy 5552 days ago | link

arc3.1. So did you get an error message on trying

  (def-func 1+1 (+ 1 1))
or what? Did you dot the func-body rest parameter as well?

-----

1 point by ylando 5552 days ago | link

It works on arc3.1.

-----

1 point by evanrmurphy 5558 days ago | link | parent | on: Initial problems

"It's alive." is just a tongue-in-cheek message printed by default to the root page (probably http://localhost:8080/) of a running instance of the Arc server. You can see where it comes from if you open the file srv.arc in your arc directory and look for the line:

  (defop || req (pr "It's alive."))
The || from that is a symbol for empty, so just as your (defop hello ...) command puts a page at http://localhost:8080/hello, (defop || ...) puts a page at http://localhost:8080/. (Nothing comes after that final slash since we used the empty symbol instead of "hello".) You could replace the default "It's alive." message by running a command like

  (defop || req (pr "jsgrahamus rox!"))
at the REPL.

Were you able to get this stuff working, by the way, or are you still stuck??

-----

4 points by evanrmurphy 5560 days ago | link | parent | on: Initial problems

> My other question is I would like to be able to search the forum. How can I do that?

The lack of an onsite search bar is a frequent question/criticism here as well as on Hacker News. Offsite, Search Arc Forum [http://af.searchyc.com/] nicely provides the functionality. Querying Google with the format

  site:arclanguage.org <your query here>
also works.

-----

3 points by evanrmurphy 5561 days ago | link | parent | on: Problems with arc

It might be more elegant to take advantage of s-expressions for this, as in

  (module mylib
    (def func-a ...))
and

  (w/module mylib
    (func-a ...))
rather than having imperative declarations that apply to an entire file.

Thinking about module/namespace systems in general, I guess as long as definitions are still global by default then they shouldn't bother anyone who doesn't want them. You might also be interested in aw's piece on library dependencies: http://awwx.ws/thinking-about-dependencies

-----

2 points by evanrmurphy 5562 days ago | link | parent | on: Ideas about arc object system.

With closures and 'deftem together, I haven't yet had the need for much more of an object system in Arc. These templates are great because they're so transparent, though I guess I've sometimes wished they were more robust (e.g. http://arclanguage.org/item?id=11855).

ylando, what do you think about 'deftem?

-----

1 point by ylando 5561 days ago | link

In my own opinion:

Shallow object systems have an advantage of better libraries design; But Arc need a real object system.

Arc need all the basic features for some one to take it seriously.

-----

2 points by rocketnia 5560 days ago | link

What do you like about having an object system, specifically? I wouldn't mind having one too, but I think object systems get complicated and arbitrary very quickly. I'd rather not have one monolithic abstraction where several highly-focused ones would do.

I do find myself switching to Groovy a lot thanks to its object system. I think what I mainly like is the ability to make an instance of FooSubclass and automatically have "foo in FooSuperclass" and "foo in FooInterface" be true.

Using Arc's built-in notion that the type of an object is the result of calling the 'type function on it (which is configurable via 'annotate), it's easy enough to achieve a form of inheritance that accomplishes what I just described:

  ; This is a table from type symbols to lists of their supertypes.
  ; Indirect supertypes are included in these lists, but no type is a
  ; member of its own list. There are no inheritance loops, either;
  ; inheritance here is a directed acyclic graph, and this is the
  ; transitive closure of that graph.
  (= indirect-inheritance* (table))
  
  (def inherits (subtype supertype)
    (~~mem supertype (cons subtype indirect-inheritance*.subtype)))
  
  (def fn-def-inherits (subtype . supertypes)
    (each supertype supertypes
      (when (~inherits subtype supertype)
        (when (inherits supertype subtype)
          (err "There was an inheritance loop."))
        (let supers (cons supertype indirect-inheritance*.supertype)
          (zap [union is supers _] indirect-inheritance*.subtype)
          (each (k v) indirect-inheritance*
            (when (mem subtype v)
              (zap [union is supers _] indirect-inheritance*.k)))))))
  
  (mac def-inherits (subtype . supertypes)
    `(fn-def-inherits ',subtype ,@(map [do `',_] supertypes)))
  
  (def isinstance (x test-type)
    (inherits type.x test-type))
  
  (def a- (test-type)
    [isinstance _ test-type])
Come to think of it, I can't think of anything else object-oriented I miss in Arc. (OO is good for dispatch too, but I've already made an Arc dispatch library I like better.) I'll make sure to try this out the next time I program something substantial in Arc.

So, I've talked a lot about me, but my question to you still stands. What features are you looking for in an object system?

-----

3 points by ylando 5559 days ago | link

In my own opinion:

The most important feature of object oriented is name compressing. Imagine a program with a lot of different databases. Now you have to give names for functions that add element, You will have to give them names like:

  add-worker, add-statistic, add-html-text ...
Now you have to remember all those names.

-----

3 points by rocketnia 5558 days ago | link

That sounds like dispatch to me. ^_^ You'd like to use one name but give it multiple meanings based on the types involved. This thread (http://arclanguage.org/item?id=11779) has a couple of approaches to dispatch from akkartik and myself.

Hmm, I've been having trouble for a while, trying to figure out my favorite way to have inheritance and multiple dispatch at the same time. (Single dispatch with inheritance seems more straightforward, but I'd rather not bother with it if I could use multiple dispatch instead.) If one method signature is (A, B) -> C, and another is (B, A) -> C, and A is a subtype of B, then what happens if you call the method with (a, a)? That could just cause an error, or the first argument could take precedence, but I'm not sure which approach I like better.

-----

1 point by ylando 5558 days ago | link

I think that multi dispatch is good idea for strong type languages. If c++ encounters this problem it will solve it at compile time (I think it will try to find the solution that is best for the first variable then the second and so on). For a dynamic language like arc multi dispatch will have an efficiency cost. In my own opinion:

It is one of the "too smart to be useful" features of common lisp. It is one of the reason people hate clos.

I have a question for you: In what way a multi dispath is better then the alternatives? You can dispatch only on the first argument or hold a virtual table of functions for every object.

-----

1 point by rocketnia 5558 days ago | link

For a dynamic language like arc multi dispatch will have an efficiency cost.

I don't think the efficiency cost for dynamic dispatch on the first argument would be significantly different, and I'm not worried about either one. I think they're at worst as inefficient as a sequence of if statements, which is to say they would take constant time (given a constant number of methods to check and constant time for each check).

Constant time can still be painful in the right quantity, and making the decision at compile time would indeed help, but Arc doesn't have the necessary static type information to go on (as you know). So multiple dispatch and single dispatch alike have to suffer a bit.

It is one of the reasons people hate clos.

Well, I've heard nothing but good things about CLOS, but then I haven't heard that much. ^_^ Is there some good anti-CLOS reading material you can recommend? XD

In what way is multi dispatch better then the alternatives?

It's partly a matter of name compression. ^_-

  ; no dispatch
  (collide-spaceship-with-spaceship s s)
  (collide-spaceship-with-asteroid s a)
  (collide-asteroid-with-spaceship a s)
  (collide-asteroid-with-asteroid a a)
  
  ; single dispatch (on the first argument)
  (collide-with-spaceship s s)
  (collide-with-asteroid s a)
  (collide-with-spaceship a s)
  (collide-with-asteroid a a)
  
  ; double dispatch
  (collide a s)
  (collide s a)
  (collide a s)
  (collide a a)
Yeah, I stole Wikipedia's example here. Another example is a comparison function that needs to compare values of many different types. Yet another is a "write" function which has different behavior for each type of writer object and each type of object to be written.

When it comes right down to it, I just believe multiple dispatch ought to be a simpler concept than single dispatch, since it imposes fewer restrictions on the programmer. Unfortunately, it seems to replace one arbitrary restriction with a bunch of (what I see as) arbitrary design decisions. ^_^;

-----

0 points by ylando 5558 days ago | link

For every one of your examples, we can use double dispatch design pattern; For example:

  (collide o1 o2) call 
  (collide-with-spaceship o2 o1) if o1 is a spaceship
  or (collide-with-asteroid o2 o1) if o1 is an asteroid.
I think that you can even abstract this design pattern with a macro (but I did not try it). So you still did not convince me that multi dispatch is a good feature.

-----

1 point by evanrmurphy 5561 days ago | link

> Arc need all the basic features for some one to take it seriously.

As long as implementing any feature for the now doesn't compromise Arc's quality in the long term, I doubt anyone here would disagree with you. Keep in mind though that Arc's core language is still subject to change (http://www.paulgraham.com/core.html).

-----


Thanks again for everyone's feedback so far. I have to be without internet for a month but will be back on here afterward.

-----


Thank you for the feedback and for fixing 'join! ^_^

> Also, note that if you're going to define your own version of falsity (no()), then the JavaScript && and || aren't necessarily going to play along with that. They'll treat "" as false, for instance.

Glad you pointed this out, may save me some debugging time. :)

Speaking of creating new structures vs. using built-in ones, I have considered switching to fake conses. That is, instead of there being a separate cons object as there is now, cons, car, cdr etc. would be array manipulations that make JavaScript arrays act just (or almost) like Arc lists. Do you have an opinion on this?

Re: 'if, the current version might seem more intuitive to a JavaScripter, but your approach may be more consistent with the way I'm expanding 'do. And then there's your point, that the latter has a close 1-to-1 correspondence of expressions with Arc while the former breaks up an expression into several statements. (Is this what you meant, or have I misunderstood?)

> As far as nested strings go, could you elaborate on that?

In the first Arc Challenge attempt I posted is the line,

  (+ |\'you said: \'| foo.value)))))
The |\'you said: \'| from that is manual string escaping I'm doing because 'js naively compiles "you said: " to 'you said: ' without considering the need for backslashes. I think it's important to be able to have JavaScript within HTML within JavaScript within HTML within ... within JavaScript, and I'm not sure it's a particularly difficult string escaping problem - I just haven't gotten it working yet.

-----

2 points by rocketnia 5577 days ago | link

...array manipulations that make JavaScript arrays act just (or almost) like Arc lists. Do you have an opinion on this?

Well, to have cons produce an JavaScript array would be a bit odd. What happens to improper lists? (Well, Arc chokes on improper lists all the time, so maybe it doesn't matter. :-p )

I think it could be a good long-term idea to support both JavaScript arrays and the Arc cons type you already have. Functions like 'all, 'map, and 'join could work for both kinds of lists, and this way people wouldn't necessarily have to change the way they're using conses, and they could work closer to the metal (or whatever JS is ^_^ ) when that was more useful.

...the latter has a close 1-to-1 correspondence of expressions with Arc while the former breaks up an expression into several statements. (Is this what you meant, or have I misunderstood?)

I'm mostly just concerned that you should be able to say things like (let x (if (< foo 2) 0 foo) (* x x)). If (if ...) translates to a statement, that won't work.

|\'you said: \'|

Oh, I see now.

Yeah, the string escaping shouldn't be that difficult. I suppose the trickiest part about string escaping is remembering to do it. ^_^

-----


Thanks. I have looked at ParenScript, but not as extensively as I probably should. Have you used it, or is there any aspect of their approach you might particularly recommend?

I'm also interested in Scheme2Js and have read much of their paper. [http://www-sop.inria.fr/mimosa/scheme2js/]

'between is courtesy of Andrew Wilcox [http://awwx.ws/between]. Nice catch. :)

-----

2 points by random7 5577 days ago | link

Thanks, it works now. (And thanks for the link to Scheme2js!)

I installed ParenScript, but haven't used it for anything.

I recommend it for having a community that actually uses it for production, and for being around long enough to have tried a variety of different approaches to hosting a lisp on top of JavaScript. It's probably worth reading through their mailing list archives to see how they've evolved.

I also recommend coffee-script, which is sort of a python/ruby syntax for Javascript. Probably the most inspiring idea from coffee-script is that the language is self-hosted (it was initially cross-compiled from ruby, but is now written in itself.)

-----

1 point by garply 5577 days ago | link

I have looked at parenscript and even started an arcscript which is totally non-functional - I was just translating it to Arc as I went as a way to understand the original codebase. I never finished it, but I'll post what I have on github and maybe we can collaborate.

Edit: pushed to github.

-----

More