Arc Forumnew | comments | leaders | submit | aw's commentslogin
2 points by aw 5416 days ago | link | parent | on: Ask "How do I do X in Arc?"

I'm making an empirical observation that the questions of this kind that I've seen have turned out, in practice, to not be useful. I'm easily disproven though -- show an example of a forum thread where a "why doesn't Arc have X?" did turn out to be useful.

I can then revise my how-to to describe which kinds of "why doesn't Arc have X?" questions are useful, or drop that part altogether.

-----

1 point by thaddeus 5416 days ago | link

Your thoughts certainly have merit - I bet the majority of these questions are in fact just complaints.

That said my comment is based on common sense, thus I'm not going to bother attempting to prove/disprove this kind of stuff. (edit: and I'm not requesting you change anything because your intent is also easily proven).

-----

1 point by aw 5416 days ago | link

Changed my mind ^_^. I think the post is stronger if it makes one point ("ask how do I do X") and makes it well, without wandering off and also talking about something else.

If I think of a more cogent argument for when asking "why doesn't Arc have X?" is or isn't useful, I'll put that in another post.

-----

1 point by aw 5416 days ago | link | parent | on: Implicit functions

have you considered just making every global implicit?

An intriguing idea!

Imagine for example you wanted to find out how often one part of your code was directly or indirectly calling "map", but you didn't all the other concurrent calls to "map" to be recorded. Easy, just parameterize "map" to do the tracing you want within the call to your code; and everything else is unaffected.

-----

1 point by akkartik 5416 days ago | link

Common lisp programs tend to define globals using defvar. Are those dynamic/special vars the same thing as racket's parameters?

-----

1 point by aw 5416 days ago | link

I haven't programmed in Common Lisp enough myself to tell for sure, but just looking at http://cl-cookbook.sourceforge.net/process.html they do appear to be similar -- at least in the sense of having a per-thread state.

-----

1 point by rocketnia 5416 days ago | link

I haven't heard of an implementation of CL with call/cc (but maybe I just haven't looked very hard XD ). Because of that, I think simulating a Racket parameter in Common Lisp would be just the same as simulating a Racket preserved thread cell (i.e. a thread-local box which is initialized in each thread to the value it had in the parent thread).

If 'defvar (and 'defparameter too?) dynamic variables have per-thread state, the next question is whether they're "preserved," and after that it's a matter of whether they have their own quirky properties or additional features apparent only in context. For instance, a Racket parameterization may or may not map well to a Common Lisp dynamic environment.

But maybe the more important question is: What do you expect from an implicit variable, and is 'defvar sufficient for that? For my purposes, any Arc global variable is (usually) sufficient, and I use Lathe's 'w/global to rebind one for a naive dynamic extent.

-----

1 point by aw 5417 days ago | link | parent | on: Database backends for Arc-based web apps?

http://www.arclanguage.org/item?id=10942 describes using HTTP/JSON to connect to MySQL via dbslayer.

-----

3 points by aw 5417 days ago | link | parent | on: Still noobing with news.arc

I still have to figure out how to redirect www. to the non-www address

The http://awwx.ws/srv-misc1 patch makes the HTTP request headers available in the request object. This includes the "Host" header, which contains the domain name the user is connecting to; i.e. "www.example.com" or "example.com" etc.

I kind of feel like I am telling a group of marathoners about how I ran a mile…

I felt the same way when I started with Arc ^_^

-----

1 point by markkat 5417 days ago | link

Thanks aw. I'm trying to make that patch happen right now. I'm hanging up on getting scheme0 reqs though. Added extend0 and scheme0 and the two defarc0 patches, but not quite sure where I am going wrong. Probably something silly. Trying to figure it out. :)

-----

3 points by aw 5417 days ago | link

Check out the "script" command (type "man script" to get the documentation). It will make a transcript of your terminal session, everything you type and everything that gets printed. You can then copy that transcript into a comment here or email it.

-----

1 point by markkat 5416 days ago | link

Ugh, that sounds like one of those 'going to work naked' nightmares. :/ BTW, thanks for the advice on the patches. -Aw is aware, but for posterity, I was loading 'scheme0.arc' after svr.arc in libs. Thanks for pointing that out aw.

-----

1 point by aw 5419 days ago | link | parent | on: inline

Wow, thanks! I've incorporated your patch into ar, and updated my post ^_^

-----

1 point by aw 5419 days ago | link | parent | on: inline

hmm! I'm going to have to look into why inline isn't working for macros in ar. In ar macros are implemented by vectors (same as Arc 3.1), and vectors aren't deep copied... so I'm wondering how the code is managing to create a new vector that would then not be eqv? to the original macro vector...?

By the way, ar is pretty awesome. It's so simple.

Why thank you :) The simplicity has been a lot of work, but was quite necessary... at least for me. Someone smarter than I am, or someone who understands the Arc 3.1 compiler better than I do, likely could have gone ahead and just implemented Arc lists with Racket mpairs directly in the Arc 3.1 compiler, but I got lost when I tried it.

-----

1 point by aw 5419 days ago | link

ah, I think it's Racket's eval which is copying the vector:

  Welcome to Racket v5.0.2.
  > (define a #(1 2 3))
  > (define b (eval (list 'quote a)))
  > a
  '#(1 2 3)
  > b
  '#(1 2 3)
  > (eq? a b)
  #f

-----

1 point by evanrmurphy 5418 days ago | link

> In ar macros are implemented by vectors (same as Arc 3.1)

I did not know this. Are functions implemented by vectors too, or does it have to do with macros being annotated functions (i.e. that annotate is implemented as some sort of vector-wrapper)?

-----

2 points by rocketnia 5418 days ago | link

annotate is implemented as some sort of vector-wrapper

That's the truth. The result of (annotate 'foo 'bar) is #(tagged foo bar), where #(...) is the external representation of a Racket vector. Note that 'tagged here is just a symbol like 'foo or 'bar.

I wonder if Arc could instead use a custom Racket type so that we don't have quirky abstraction leaks when using Racket vectors. I never actually find myself wanting to use vectors, and if I did, I'd just [annotate 'vector _] them, but still. :-p

Are functions implemented by vectors too

They're implemented as Racket functions.

-----

1 point by aw 5418 days ago | link

I wonder if Arc could instead use a custom Racket type

Very easily -- it's just a matter of changing a couple lines of code to use a struct instead of a vector. I'll add it to my todo list if you'd like.

-----

2 points by shader 5418 days ago | link

I did an experiment where annotate produced a list, of the form ('tagged x type1 type2 ...), making the tagged lists transparent objects to the arc system. In doing so, I extended the type system to include the original type of the object in the list and support more than one type, allowing a simple form of inheritance through coercion. I.e. if you annotated a list as type 'foo, until you defined an actual coercion method for converting 'foo to a cons it would be treated as a normal list, and you wouldn't lose any ability to work with it using existing operations.

The thing that annoys me the most about arc's current type system is that if you tag something, it becomes an unusable vector according to all existing arc code, so you need to re-implement or extend any function that you actually want to support the new type.

-----

2 points by akkartik 5418 days ago | link

Hmm, it sounds like just making it a tagged list instead of a tagged vector wouldn't address your criticism. Any other suggestions?

-----

1 point by evanrmurphy 5418 days ago | link

I think he made the additional change of delegating all functional calls to the "parent" type when they didn't explicitly handle the type at hand. This makes a lot of sense. If you have a list that's tagged 'foo, it should behave exactly like a normal list does until you've specified some diverging behavior for type 'foo.

Do you still have the code for your experiment, shader?

-----

1 point by shader 5416 days ago | link

I do, but it was built on the old anarki master, so I'm going to have to spend a little bit of time updating it.

-----

1 point by akkartik 5418 days ago | link

Ah, I didn't properly read that first para somehow!

-----

1 point by rocketnia 5418 days ago | link

I'll add it to my todo list if you'd like.

Like I said, it hardly matters to me 'cause of the [annotate 'vector _] workaround.

More worthwhile would be having custom 'iso hashing and stuff like that. ^_^ That's something that would probably benefit from a dedicated Racket type for tagged values, but that's not necessarily the only way to go about it. I'm still trying to figure out how to go about it for Penknife....

-----

1 point by evanrmurphy 5418 days ago | link

Ah, thanks for explaining that. It's very clear now.

-----


In what way are Unicode characters troublesome? (Do you have an example of a browser that fails to render UTF-8, or...?)

-----

3 points by dpkendal 5419 days ago | link

It's not that they're troublesome to render in simple circumstances, but consider:

1. Alice is writing a blog entry declaring her unrequited love for Bob.

2. Alice includes a quote from Bob's blog by copying-and-pasting. Bob is using UTF-8 charset, and the copied section includes some Unicode curled quotes, because Bob is typographically sensitive.

3. Because Alice is using a backwards text editor which refuses to believe there is something other than 1 byte = 1 character and plain ASCII in the lower half, it shows the characters exactly as Alice and Bob intended (such a third-rate text editor is sure to be using the operating system's standard text editing control, which will know about such tricks) -- but internally it has crapped up the representation, and lo:

4. When Alice submits this onto her ISO-8859-1-encoded blog, she will have mixed character sets and invalid XML and all of a sudden her well-written love letter is smeared by �s where there ought to be “s and ”s.

Further reading:

- http://textism.com/article/663/pomegranate

- http://daringfireball.net/2003/02/short_and_curlies

- http://www.alistapart.com/articles/emen/

-----

1 point by aw 5418 days ago | link

Ah, I understand. Your goal is to encode Unicode text in HTML which is itself encoded in ASCII only, so it can be transmitted through channels (such as bad editors) which mess up non-ASCII text.

To encode any Unicode text this way we'd also want to encode HTML special characters such as <, >, and &; but that could be done before calling your routine.

-----


Yes, I find I' often write a macro whose only purpose is to allow a "body" to be written without having to enclose it in a function. For this specialized purpose, it'd be nice to have a macro defining macro to do that... though I haven't thought about how to do that myself yet.

-----

3 points by aw 5429 days ago | link | parent | on: Noob question.

If you want to try out first-class macros to see what they could do for you, that's easy enough: write an interpreter for Arc. It'd be slow of course, but enough so that you could try out some different kinds of expressions and see if you liked what you do with it.

-----

1 point by evanrmurphy 5429 days ago | link

Yes. I'm actually taking a similar approach with more instant gratification: try using a lisp that already has them. http://picolisp.com/5000/-2.html

-----

2 points by rocketnia 5428 days ago | link

I was a fan of fexprs not too long ago, and I still kinda am, but they lost their luster for me at about this point: http://arclanguage.org/item?id=11684

Quoting from myself,

Quote syntax (as well as fexprs in general) lets you take code you've written use it as data, but it does little to assure you that any of that computation will happen at compile time. If you want some intensive calculation to happen at compile time, you have to do it in a way you know the compiler (as well as any compiler-like functionality you've defined) will be nice enough to constant-propagate and inline for you.

I've realized "compiler-like functionality you've defined" is much easier to create in a compiled language where the code-walking framework already exists than in an interpreted language where you have to make your own.

If part of a language's goal is to be great at syntax, it has a conflict of interest when it comes to fexprs. They're extremely elegant, but user libraries can't get very far beyond them (at least, without making isolated sublanguages). On the other hand, the dilemma can be resolved by seeing that an fexpr call can compile into a call to the fexpr interpreter. The compiler at the core may be less elegant, but the language code can have the best of both worlds.

This is an approach I hope will work for Penknife. In a way, Penknife's a compiled language in order to support fexpr libraries. I don't actually expect to support fexprs in the core, but I may write a library. Kernel-style fexprs really are elegant. ^_^

Speaking of such Kernel-like libraries, I've thrown together a sketch of a Kernel-like interpreter written in Arc. It's totally untested, but if the stars have aligned, it may only have a few crippling typos and omissions. :-p https://gist.github.com/778492

Can't say I'm a fan of PicoLisp yet, though. No local variables at all? Come on! ^_^

-----

1 point by evanrmurphy 5428 days ago | link

> Can't say I'm a fan of PicoLisp yet, though. No local variables at all? Come on! ^_^

Hmm... not sure what you mean by this. I can define a local variable at the PicoLisp REPL using let just as I would in Arc:

  : x   
  -> NIL
  : (let x 5
      x)  
  -> 5
  : x     
  -> NIL
The rest of your comment was really interesting. Thanks for the links!

-----

1 point by rocketnia 5428 days ago | link

Sorry, I spoke too soon. I could tell 'let and function arguments would be possible, but I was a bit put off by http://software-lab.de/doc/ref.html#conv. From http://www.prodevtips.com/2008/08/13/explicit-scope-resoluti..., it sounds like dynamic scope. Is that right? (I'm not in a position to try it out at the moment. >.> )

Speaking of speaking too soon, I may have said "user libraries can't get very far beyond [an fexpr language's core syntax]," but I want to add the disclaimer that there's no way I actually know that.

In fact, I was noticing that Penknife's parse/compile phase is a lot like fexpr evaluation. The operator's behavior is called with the form body, and that operator takes care of parsing the rest, just like an fexpr takes care of evaluating the rest. So I think a natural fexpr take on compiler techniques is just to eval code in an environment full of fexprs that calculate compiled expressions or static types. That approach sounds really familiar to me, so it probably isn't my idea. :-p

-----

1 point by evanrmurphy 5428 days ago | link

No harm done. :) PicoLisp appears to have lexical scoping but dynamic binding, although my PLT is too weak to understand all the implications of that. From the FAQ:

> This is a form of lexical scoping - though we still have dynamic binding - of symbols, similar to the static keyword in C. [1]

> "But with dynamic binding I cannot implement closures!" This is not true. Closures are a matter of scope, not of binding. [2]

---

[1] http://software-lab.de/doc/faq.html#problems

[2] http://software-lab.de/doc/faq.html#closures

-----

2 points by rocketnia 5428 days ago | link

Sounds like transient symbols are essentially in a file-local namespace, which makes them lexically scoped (the lexical context being the file!), and that transient symbols are bound in the dynamic environment just like internal symbols are. So whenever lexical scope is needed, another file is used. Meanwhile, (====) can simulate a file break, making it a little less troublesome.

-----

1 point by evanrmurphy 5428 days ago | link

But the let example I gave a few comments ago didn't use a transient symbol. Why does it work?

I chatted with PicoLisp's author, Alexander Burger, yesterday on IRC. If I catch him again, I can ask for clarification about the scoping/binding quirks.

-----

2 points by rocketnia 5428 days ago | link

I think it works because while you're inside the let, you don't call anything that depends on a global function named x. :) That's in the FAQ too:

-

What happens when I locally bind a symbol which has a function definition?

That's not a good idea. The next time that function gets executed within the dynamic context the system may crash. Therefore we have a convention to use an upper case first letter for locally bound symbols:

  (de findCar (Car List)
     (when (member Car (cdr List))
        (list Car (car List)) ) )
;-)

http://software-lab.de/doc/faq.html#bind

-----


Assuming you don't change the syntax of dotted lists, a problem is that you wouldn't be able to use an expression for "xs".

The dot notation creates a cons for you, and a cons creates a regular list if its second argument is nil or another cons (which itself is a regular list).

Thus

  '(a . (b))
works like

  (cons 'a '(b))
which in turn is like

  '(a b)
which you can see for yourself:

  arc> '(a . (b))
  (a b)
So an expression like

  (bar x . (foo))
that we'd want to work like

  (apply bar x (foo))
is parsed by the reader like this:

  arc> '(bar x . (foo))
  (bar x foo)
and by the time the compiler sees the expression there's nothing there to tell it that a dot was used.

Of course, if you change the reader so that a dot doesn't produce a dotted list but instead creates a token for the compiler to see, then you can do whatever you want... though you'd also need to extend the compiler to handle the dot notation in the other places which is currently handled by the reader.

-----

2 points by rocketnia 5433 days ago | link

Great point.

For what it's worth, 'apply could be moved to arc.arc:

  (def apply (self . args)
    (zap rev args)
    (zap [rev:+ (rev:car _) cdr._] args)
    (self . args))
I think the number of times I use 'apply with a variable in the final position is enough for the syntax to be relevant to me... but then I'd be likely to refactor (a b c . d) into (apply a b c (something-else)) and vice versa all the time, which would be a bit of a pain. Then again, it's balanced against the cost of refactoring (a b c) into (a b c . d) and vice versa....

by the time the compiler sees the expression there's nothing there to tell it that a dot was used.

In Racket's syntax there is a way, I think. It makes syntax more complicated than just its conses, though. You'd have to use an Arc variant of syntax-quasiquote (or just syntax-quasiquote) to construct it in macros.

Meanwhile, the (cdr `(foo . ,<scheme-expr>)) quirk would become more of a bug than it already is. But then I assume whatever Arc hack implements this syntax would also have '$ built in, so there's probably no point to keeping the quirk around.

-----

More