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

Wow, thanks!

This may not an issue for you or for your own work environment, but if I continue to publish techniques that people wish to share professionally I'm imagining that some may find the name "Cat Dancer" to be an unnecessary distraction. So I put up another copy here in case:

http://andrewwilcox.name/parser-combinator-approach-to-json....

-----

1 point by ecmanaut 5899 days ago | link

Unrelated, but I would advise against working for or with people that would either choke on an online alias (that is not even inflammatory :-), and/or fail to grasp at the quality of your work, reasoning and communication about the concepts therein, measuring your aptitude from that data.

...but I'll definitely hand you that signing it with your contact information likely makes it easier for those that do spot you to get in touch, for whichever reason. Which might sometimes be more interesting than vetting for ideal recruiters, especially if you want to work someplace that delegates recruiting to people outside of where the actual work happens, so the above paragraph gets half moot.

-----

1 point by CatDancer 5901 days ago | link | parent | on: (coerce 0 'num)

Why is this invariant important?

-----

1 point by rntz 5901 days ago | link

It's more or less what coerce means.

-----

2 points by CatDancer 5901 days ago | link

In arc3 I can already ask 'coerce to convert something for me into some general type and get back a more specific subtype:

  arc> (type (coerce "0" 'num))
  int
Maybe that's ok.

-----

1 point by rntz 5901 days ago | link

Hm. I wasn't thinking of it in terms of sub- and super-types, but in that context it makes sense. Thinking this way, if 'int is a subtype of 'num, then (isa 2 'num) should ideally return t; unfortunately it's nil in the present arc. :( I guess we'll just have to chalk arc's handling of types up as a bit of leaky abstraction and leave it be. I'll go push a fix for (coerce 0 'num) to anarki.

-----

2 points by CatDancer 5901 days ago | link

  (def isa (x y)
    (or (is (type x) y)
        (and (is y 'num) (is (type x) 'int))))

  arc> (isa 34 'num)
  t
On the one hand, this seems like the "right" answer, on the other hand, so far I've haven't needed this.

-----

1 point by CatDancer 5902 days ago | link | parent | on: (coerce 0 'num)

ah, the

  ((eqv? type (ar-type x)) x)
line doesn't match because the ar-type is 'int

-----

1 point by CatDancer 5902 days ago | link | parent | on: New ppr function

Just out of curiosity, and I haven't used 'src since I'm not on Anarki, but for that particular application, I was wondering if it would be useful to show the actual source of the function or macro, as it appears in the original source file?

-----

1 point by shader 5902 days ago | link

'src is very helpful, I use it all the time.

However, using the code from the source file is not always possible as you may have typed it in from the repl, or that file may have changed.

Also, many people may not actually indent their code properly, and 'src presumably should provide some sort of standardization.

The only reason that I can think of for reading the text directly from the source file would be that you would get all of the comments as well, not just the docstrings.

So far the ppr function indents the code surprisingly well, and I've actually used it sometimes to figure out how I should be indenting my code ;)

-----


You might look at prompt.arc for a starting point. It allows Arc expressions to be evaluated from a web page; your IDE could connect to the running Arc process as an HTTP client and evaluate Arc expressions in the same way.

-----

1 point by tokipin 5900 days ago | link

cool, i'll probably try that out

-----

1 point by CatDancer 5904 days ago | link | parent | on: Labeling hacks

How will meta-data be transfered?

Haven't really thought about it yet... :)

One option that I can think of is to just put it at the top of the file containing the hack.

That would prevent the information from being changed, since a hack (with a particular label) needs to be immutable.

So, another option would be to have the info distributed as a file with the same name as the hack, but a .info extension

That would work.

-----

1 point by CatDancer 5904 days ago | link | parent | on: Labeling hacks

I think there's no problem with that as long as you have some mechanism that helps people not publish hacks out of Anarki that end up with the same label.

For example, I haven't tried it, but if git prevents me by default (if I don't use a force option or something) from pushing a tag to a repository that already has that tag, and you're using tags for the label, then that would do the trick.

-----

1 point by CatDancer 5904 days ago | link | parent | on: Labeling hacks

If the version information is intended to convey meaningful information (such as major release vs. minor release, alpha vs. stable, etc.), then I'd put that in the information about the hack, instead of in the label.

For publishing a release, I'd personally use http://website/shader.ppr0.arc for the sake of typing less dots, but http://website/shader.ppr.0.arc is fine too.

The way git is normally used by other projects is that files don't contain version or release numbers, and when a release is made a package file is created (a zip or a tar or whatever), that contains the unique version or release number (foo-1.34.03.zip). So, in the same way, you could take a ppr.arc file that you have in git and publish it as shader.ppr0.arc, shader.ppr1.arc, etc.

-----


I use A, for me the space taken up by the extra indentation is less than the extra line taken up for B.

I don't use indentation as a way to indicate whether I'm calling a function or using a macro.

-----

1 point by shader 5904 days ago | link

Next question:

Should case be indented like 'if:

  (case
    a
      (b     )
    c
      (d     )
    (e      ))
or in pairs like with:

  (case
     a (b    )
     c (d    )
     (e     ))
?

Should it depend on whether they fit on one line or not? If they don't fit, should it still be like b., just with the second part spilling onto the next line?

-----

1 point by CatDancer 5904 days ago | link

I use the second if it fits OK, or the first if they don't fit.

-----

1 point by absz 5903 days ago | link

Ditto, except I write

  (case
    a-short     (b ...)
    c-very-long (d ...)
                (e ...))
when everything is on one line, and

  (case
    a-short
      (b ...)
    c-very-long
      (d ...)
    ; else
      (e ...))
when it doesn't (though I go back and forth about the ; else).

-----

1 point by shader 5902 days ago | link

Your first version is the one currently implemented by ppr.arc. If you would like, you can write the indentation function for your second version (it can even include the "; else")

Otherwise I think that the first version is generally clearer, and the second is rarely needed, as the value of the case statement can't usually be very long. Could you give me an example where you use your second version?

-----

1 point by absz 5902 days ago | link

Sure; here's something from my tagged-unions.arc on Anarki (Arc 2). It's responsible for parsing the types specified for slots in the tagged union:

  (each type-frag types
    ; Assemble the ('type name) pairs into two lists, so that we can iterate
    ; through them.
    (case (type type-frag)
      ; If it's a symbol, then we're defining a new name; add a new set of
      ; values, and go.
      sym
        (do
          (zap [cons type-frag _] names)
          (zap [cons nil       _] values))
      ; Otherwise, we're adding a value to an existing variant.
      cons
        ; I changed my mind about the order (now it's (name pred?) instead of
        ; (pred? name)), so I'm reversing it here.
        (zap [cons (rev type-frag) _] (car values))
      ; else
        (err "Invalid member of tagged union declaration.")))
I should also add (just as another data point) that my multi-condition ifs look like that too, and single-condition ifs look like the following:

  (def macexn (n expr)
    " Macroexpand `expr' `n' times.  NB: `expr' *is* evaluated!
      See also [[macex1]] [[macex]] "
    (if (and (number n) (> n 0))
      (macexn (- n 1) (macex1 expr))
      expr))
I'm not hugely wedded to any of my conventions, though, and I haven't coded in Arc for quite a while anyway; this isn't intended to get you to change anything or convert people to my style. As I said, it's just another data point.

-----

2 points by CatDancer 5904 days ago | link | parent | on: A new anarki

I'm still not sure what should be done regarding libraries

There are some advantages to keeping each library in its own branch:

- It makes the git development history for the library really clear.

- I can propose changes to a library and merge them in to the library branch, without getting messed up by independent merges happening to other libraries.

- If you're using library A and someone commits a change to library B which breaks A, but you can't go back because someone later committed C which you need, what do you do? Make a commit that reverts the B change? But what if someone else is using that B change? Separate branches avoids these kinds of conflicts.

But, of course keeping libraries in separate branches does make using the libraries harder. Instead of just checking out one branch, now you need to use the published versions of the libraries, or checkout a git repository for each library.

I do no longer recommend my idea of having the git commits for a library include their dependencies. That was a good experiment for me to try, and I learned a lot from it, but it turned out not to be useful.

If you do decide to give each library its own branch, then I recommend that the library branch not include the Arc sources: make it an independent branch. The easiest way to do this is to add the library to a new, fresh git repository, and then fetch the library commit into your Anarki repository as a branch.

-----

1 point by shader 5904 days ago | link

I also agree with separate branches for each library. For one thing, it takes less effort to make the branch stand alone, and there is less chance of messing things up.

Also, they don't get in the way as you are not forced to read the list, and can choose to track as many or few remote branches as they like.

How about using one branch per library, and tags for versions? That way everyone can track the development and even add things, but the versions are the things that 'lib and others like it go for.

The only thing I'm wondering about branches for libraries is: how do you find them if you're trying to fetch them via 'lib? I think only major changes need to be in their own branches, like the hygienic macro system. Everything else should either be hosted separately or in the lib folder.

-----

1 point by CatDancer 5904 days ago | link

The only thing I'm wondering about branches for libraries is: how do you find them if you're trying to fetch them via 'lib?

I can think of three scenarios:

1. You're using the public, published version of a library that also happens to be in your git repository.

2. You're using an unpublished version of a library in your git repository: for example, you're testing your code against the latest development version of a library to see if they work together.

3. You're working on a library.

For #3, I presume you'd just be using 'load.

For #2, if you want to for example get the latest version of a file "foo.arc" in the "foo" branch, you can use git for that, e.g.:

  git show foo:foo.arc
For #1, you don't need to get the library out of git, you can use whatever mechanism we're all using to fetch and use a published library.

-----

1 point by shader 5904 days ago | link

For #3, I presume you'd just be using 'load.

I was hoping to use a modified version of 'lib that would allow me to type

  (lib binary)
when I meant

  (load "lib/binary.arc")
It has the advantage of less typing, and hopefully the concept that functions are not reloaded unless the file has changed. If I'm trying to test a new version of a function, I would rather selectively reload that function than the whole library.

-----

More