Arc Forumnew | comments | leaders | submitlogin
Setting up Penknife
3 points by rocketnia 5102 days ago | 6 comments
I touched up Penknife over the weekend and got it into a working, pseudo-presentable state. ^_^ It's not the first time it's worked, but I started doing more development than testing at one point, and I hadn't brought it up to date with Rainbow in a while. For now, it should work, and it's quite a bit easier to load than it was a few days ago. ^_^

Penknife is intended for either Rainbow, official Arc 3.1, or Anarki, and I prefer Rainbow for its speed. Load Lathe and Penknife like so:

  (= lathe-dir* "my/path/to/lathe/arc/")
  (load:+ lathe-dir* "loadfirst.arc")
  (= penknife-dir* "my/path/to/penknife/")
  (load:+ penknife-dir* "penknife.arc")
At this point, Penknife doesn't do a lot. The runtime is fairly comprehensive, but there's not much of a standard library. Nevertheless, it might be effective as a scripting language for Arc if you can figure out how to use it. This might get you started:

  arc> (pkrepl)
  pk> [list q.a q.b q.c]
  ("a" "b" "c")
  pk> [arc (trim " example Arc code ")]
  "example Arc code"
  pk> [fun square [x] [arc.* x x]]
  ...lots of output...
  pk> square:arc.4
  16
  pk>
    [let arcsym arc.sym
      [mac* sym [] body
        qq.[arcsym q[\,body]]]]
  ...lots of output...
  pk> sym.my-symbol
  my-symbol
  pk> arc.type:sym.my-symbol
  sym
  pk> [sym symbol-starting-with-a-space--so-dont-do-this]
  | symbol-starting-with-a-space--so-dont-do-this|
  pk> sym[symbol with intentional spaces in it]
  |symbol with intentional spaces in it|
  pk> arc.bound:sym.unbound-arc-var
  nil
  pk> [arc bound&eval]:sym.unbound-arc-var
  nil
  pk>
    [fun & [a]
      [hf [b]
        ; Most Penknife lambda forms make reflection-friendly closures
        ; ("hefty-fns"), whereas tf and tf* make regular Arc closures
        ; ("thin-fns"). We're using Arc closures here so that Arc can
        ; call them, but I usually avoid thin-fns when I can for fear of
        ; premature optimization, even though Penknife doesn't actually
        ; have any standard reflection utilities yet.
        [arc.andf [tf* [] args [apply a args]]
                  [tf* [] args [apply b args]]]]]
  ...lots of output...
  pk> arc.bound&[arc eval]:sym.unbound-arc-var
  nil
  pk> [arc (= unbound-arc-var "My life is a lie! :D")]
  "My life is a lie! :D"
  pk> arc.bound&[arc eval]:sym.unbound-arc-var
  "My life is a lie! :D"
  pk> drop.
  goodbye
  arc>
If you try out Penknife but get stuck, let me know so I can explain or apologize for whatever you've encountered. ^_^


1 point by rocketnia 5102 days ago | link

So you can reproduce the example now and in the future, here's a list of links to present-day versions of the dependencies:

Rainbow: https://github.com/conanite/rainbow/commit/aa37d65548d5658aa...

Racket: http://download.racket-lang.org/racket-v5.0.2.html

Anarki: https://github.com/nex3/arc/commit/8fb05f13830f793f3cbb24faa...

Lathe: https://github.com/rocketnia/lathe/commit/50e21d4df2870455e6...

Penknife: https://github.com/rocketnia/penknife/commit/3b1c161b351ae75...

-----

2 points by SteveMorin 5101 days ago | link

For those of us who don't know what is the purpose of pen knife?

-----

3 points by rocketnia 5099 days ago | link

Thanks for asking. ^_^ (And thanks for any patience you haven't lost! XD )

Penknife's a programming language. I have a very specific opinion of what programming languages will become (http://arclanguage.org/item?id=12993), and I'm making Penknife in the hope that it's a well-designed first foray into that world—well-designed in the gemlike sense of not being everything to everybody but being as flawless as possible for what it is. Penknife has two very specific purposes:

- To have a customizable syntax that's fine at the start but almost limitlessly excellent once it's been customized.

- To be great at code generation, so that even if you think you want to use another language, you're likely to be more productive if you generate that code using Penknife instead.

The point is for Penknife to be a language useful to as many people as possible for as long as possible, so that it can continue to be more and more useful as its library support improves. This is sort of a world domination plot, but it isn't really (I promise :-p ). Penknife will probably only dominate syntax design (not platform design, where security and performance are hot topics), and even then it'll probably only dominate sequence-of-commands-style syntax design (the kind good at REPLs, as opposed to the landscape-of-declarations style good in IDEs). Even then, there'll be people who can't stand the foundations upon which their code generators are built; you can't please everyone. That being said, I think Penknife does stand a very real chance of monopolizing a big segment of the programming experience, so I think it's important for a gemlike language to get there first, before a hackish one has the benefit of entrenchment.

To minimize the number of fiddly mistakes (and other hackishness) in Penknife, any complexity-introducing feature that's only rarely needed for the above purposes is to be left out. Two examples are reentrant continuations and concurrency. A lack of continuation support may force certain syntaxes to be implemented without the help of continuations for coroutines or backtracking, and a lack of concurrency may hobble some theorem-proving-heavy compilers, but I doubt that'll be everyday Penknife programming. When such a nightmarish situation does come up, it's probably time to use an FFI or system call, and since you can use Penknife to generate the program you're calling that way, it shouldn't be too bad. :-p

It's quite a bit arrogant of me to think Penknife will be gemlike anytime soon, let alone that it'll still be seen as gemlike in the future. I'm still in the process of adding language features I dearly hope won't make it to the final product in their current form. Still, I think I'm the person who best knows where the heck I'm going with this project, and I intend to use Penknife myself all the time, so I'm following my passion. Feedback and help are welcome, of course!

For syntax experimentation, my favorite existing language is Arc. The Arc Forum community's very particular about every little syntactic detail. :-p So it should be no surprise that Penknife's design borrows heavily from things I like about Arc, while fixing things I don't like. For instance:

- Infix syntax is now seamless with the language. Penknife infix operators follow the normal scoping rules, as shown in the example.

- Penknife syntaxes take arbitrary []-balanced textual code, not just s-expressions, as their bodies. This allows for custom syntaxes to behave the same way as built-in "literal" syntaxes like q[...]. Case in point: the example's sym macro.

(There's more information about the above two points at http://arclanguage.org/item?id=13079.)

- Penknife has a hygienic macro system built on top of its more general-purpose syntax system (although only this high-level macro system is exposed to Penknife for now, and I'm pretty sure it's buggy despite it currently passing every test I've come up with :-p ). It's designed to work harmoniously with a module system I've also been working on. I consider both hygiene and modules to be scoping issues, so I aim to tackle them using environments, and given that premise, I figure a module import is going to be a matter of replacing the interaction environment with a local environment that shadows it, so I generally try to minimize the idea that there's a global environment at all when I can. Thus, for hygiene's sake across modules, I have each macro capture its lexical environment like a closure, and this is why [let arcsym arc.sym [mac* ...]] works in the example.

The next step is finishing up the rest of the features needed for fundamental syntax customization, especially the module system and a standard library. Then it's a matter of developing Penknife applications and seeing what happens.

-----

2 points by evanrmurphy 5101 days ago | link

It's a programming language that rocketnia is designing. He previously posted about it at http://arclanguage.org/item?id=13071.

-----

1 point by rocketnia 5100 days ago | link

Thanks a lot for the prompt and accurate response! ^^; Within hours of the question, I'd composed most of a fairly substantial response, but since then I've been too busy and/or tired to finish it up and post it. Thanks for taking the initiative to give the short version. :)

-----

1 point by evanrmurphy 5099 days ago | link

Welcome. :)

-----