Arc Forumnew | comments | leaders | submitlogin
1 point by jsgrahamus 1 hour ago | link | parent | on: Ask ARC: Can I start with Arc?

Recommend working through the tutorial, too.
3 points by akkartik 1 day ago | link | parent | on: Ask ARC: Can I start with Arc?

I think "learning Lisp" is Arc's best niche. So yes, try using it and come ask us questions. Feel free to also ping me over email, that is sometimes faster. My address is in my profile.

One caveat: it can be easier to learn from a book if you follow the language it was written for. Land of Lisp is a fine book by all accounts, so if you use it you may be better off just using Common Lisp or whatever. But feel free to come ask questions anyway. Maybe we can show you both Common Lisp and Arc versions of programs.


Whoa, I could have sworn I responded to this one :/

rocketnia is right that I tend to just run Arc from within its directory, keeping it alongside any Arc program I may be working on at the moment. As a result, I'd kinda always assumed you could run it from anywhere and find yourself in the Arc directory once you loaded up. Now I find this isn't the case:

  $ pwd
  /home/akkartik
  $ ./anarki/arc.sh
  arc> ($:current-directory)
  #<path:/home/akkartik>
This was initially surprising, but of course we're only parameterizing the current directory while loading libraries: https://github.com/arclanguage/anarki/blob/c3849efaf9/boot.s...

I'm not sure what to do about this. In addition to rocketnia's `current-load-file*` suggestion, should we just expose `arc-path` from boot.scm? I couldn't immediately see how to get to it from Arc.


I've always been frustrated with Arc's lack of a standard practice for loading dependencies (although I suppose akkartik might consider that a feature ^_^ ).

If the way Arc's lib/ directory has been used is any indication, the way to do it is:

- Start in the Arc directory when you run Arc, and never cd out of it.

- (load "lib/foo.arc"), or (require "lib/foo.arc") if you want to avoid running the same file multiple times

But I think for some Anarki users, the preferred technique has been somewhat different:

- Invoke Anarki from any directory.

- Ignore lib/ as much as possible. On occasion, load a library from there by using (load "path/to/arc/lib/foo.arc"), but a few libraries may make this difficult (e.g. if they need to load other libraries).

When I started writing Arc libraries, the first thing I wrote was a framework for keeping track of the location to load things relative to, so that my other libraries could load each other using relative paths regardless of which of the above techniques was in use. But the Lathe module system didn't catch on with anyone else. XD

More recently, eight years ago, rntz implemented the current-load-file* global variable that may make it easier for Anarki-specific libraries to compute the paths of the libraries they want to load. Nothing is currently using it in Anarki however.


It's reading the invalid sequence as � U+FFFD REPLACEMENT CHARACTER, which translates back to UTF-8 as EF BF BD (as we can see in the actual results above). The replacement character is what Unicode offers for use as a placeholder for corrupt sequences in encoded Unicode text, just like the way it's being used here.

The Pike maxim "A little copying is better than a little dependency" comes to mind. I think the overhead of dependencies is underrated ("it's just a 1 line import statement!"), and often a little repetition is a good thing.
3 points by zck 5 days ago | link | parent | on: Install Issues

It's completely normal that you're having issues. The official Arc documentation is...lacking.

The "latest" arc is Arc 3.1, but that came out in 2009. You can download it here: http://arclanguage.org/item?id=10254, and start it up with `racket -f as.scm`. (Note that you no longer need the specific version of MZScheme you used to; you can use racket.) No, this information has not been updated on the official Arc install page. Yes, this is frustrating.

Alternately, you have the option to use Anarki, the community-supported version. Documentation is here: http://arclanguage.github.io/


Thanks, akkartik. Also read the discussion on Gerbil.

Found on the recent HN discussion about Gerbil Scheme: https://news.ycombinator.com/item?id=15394603

One interesting point here is how he prioritizes choice of language based on relationships. This connects up with my comment on avoiding dependencies at http://arclanguage.org/item?id=20221. The conventional wisdom that the community of a language matters more than its technical attributes is a diluted version of this idea.


COPYMORE

I'm what I like to call a 'copyista': I think DRY is overrated, and abstraction is overrated, and people are too quick to create abstractions to compress code rather than for conceptual clarity. Some links: http://www.sandimetz.com/blog/2016/1/20/the-wrong-abstractio...; http://programmingisterrible.com/post/139222674273/write-cod...; http://bravenewgeek.com/abstraction-considered-harmful; http://akkartik.name/post/modularity; http://dimitri-on-software-development.blogspot.de/2009/12/d...; http://thereignn.ghost.io/on-dry-and-the-cost-of-wrongful-ab...; http://akkartik.name/post/habitability. You don't have to read them all, but hopefully this gives you as much flavor as you want :)

NODEPS

This is short for "no dependencies". I think a lot of software's ills stem from people's short-sighted tendency to promiscuously add dependencies. In fact, our fundamental metaphor of libraries is wrong. Adding a library to your program isn't like plugging a new block into your Lego set. It's like hiring a new plumber. You're not just adding a few lines of code to a file somewhere, you're creating a relationship. Everytime I see someone talk about "code smells", I wait to see if they'll bring up having too many dependencies. Usually they don't, and I tune them out. And the solution is easy. When you find a library that does something useful, consider copying it into your project. That insulates you from breaking changes upstream, and frees up upstream to try incompatible changes. As a further salubrious effect, it encourages you to hack on the library and tune it to your purposes. (Without giving up the options of merging further changes from them, or submitting patches upstream.)

As it happens, this worldview of mine was actually catalyzed by conversations here in the Arc Forum, most proximally http://www.arclanguage.org/item?id=13263. That thread led to me writing http://akkartik.name/post/libraries and (a little clearer) http://akkartik.name/post/libraries2.

I consider an example of exemplary library use to be how I copied the termbox library into Mu (https://github.com/akkartik/mu/commit/5f1285238b), periodically merged commits from upstream (https://github.com/akkartik/mu/commit/9ba313ab7f), gradually cleaned it up to fit better with my project (https://github.com/akkartik/mu/commit/9a31c34f0f), and gradually stripped out code from it that Mu does not require (https://github.com/akkartik/mu/commit/c04baba4f2; https://github.com/akkartik/mu/commit/8e7827dfcf; https://github.com/akkartik/mu/commit/547ec78bf2). In the process I made some wrong turns, deleting features that I later decided I wanted (https://github.com/akkartik/mu/commit/10a3b8cca2) and created bugs for myself (https://github.com/akkartik/mu/commit/3315a7d3bb; https://github.com/akkartik/mu/commit/0c0d1ea5cd). But when it did things I didn't want, I was now empowered to change them (https://github.com/akkartik/mu/commit/ee1a18f050). One of my patches was useful upstream, so I submitted it: https://github.com/nsf/termbox/commit/0730826a07. I would be in no position to submit that patch if I hadn't taken the trouble to understand termbox's internals. That's another benefit of copying and privately forking libraries: it makes you a better citizen of the open source world, because open source depends on eyeballs, and using a library blindly helps nobody except your (extremely short-term) self.

More broadly, Mu is suffused with this ethos. My goal is that if you have a supported platform you should be able to run it with three commands:

  $ git clone https://github.com/akkartik/mu
  $ cd mu
  $ ./mu
(That highlights another benefit: your software becomes easier for others to try out. Without giving out binaries, because what's the point of being open-source if you do that?)

Mu's also geared to spread this idea. I want to build an entire software stack in which any part is comprehensible to any programmer with an afternoon to spare (http://akkartik.name/about). Which requires having as little code as possible, because every new dependency is a source of complexity if you're building for readers rather than users. In chasing this goal I'm very inspired by OpenBSD for this purpose. It's the only OS I know that allows me to recompile the entire kernel and userland in 2 commands (https://github.com/akkartik/mu/wiki/Building-OpenBSD-on-Open...). People should be doing this more often! I think I'm going to give up Mu and build my next project atop OpenBSD. But that's been slow going.

---

Ah, here's an old HN thread where I managed to combine both these ideas: https://news.ycombinator.com/item?id=11158357#11189308

I'd have preferred to more directly call out my hatred for compatibility constraints, but I couldn't figure out how to fit it on a license plate :)


Do you have any references for those terms? Or a short explanation for them?

That's precisely where I found out about it :D
2 points by breck 15 days ago | link | parent | on: 3-Dimensional Source Code

Thanks for this link. I hadn't studied Rebol too closely before.

I do like Rebol's embrace of dialecting and I think there's opportunity in making composing languages better.


Mine would be COPYMORE. Or NODEPS.

I think I share your vision: http://arclanguage.org/item?id=17277


Such a great talk, like his others.

I think it would be great to live in a world where not only could you use your finger to create a sprite animation, but if curious, you could also more easily delve into all the black boxes that make that experience happen (down to the physical level).

I like the NOMODES license plate. If you all had to pick a license plate to describe your work, what would it be? I might go with NOPARENS or NOSYNTAX.


I was just thinking about it yesterday, after reading https://www.theatlantic.com/technology/archive/2017/09/savin.... Very inspiring talk.

I'm sure many of you have already seen this (it's from 2012...), but it seems relevant to the discussion we were having about the future of programming.

He makes the great point that we should be enabling creation, and tightening the feedback loop between thought and product. I've been mostly focusing on better was to represent thoughts and communicate them to the computer, but this draws attention to the purpose of programming itself.


This was my first thought as well. But why does `readc` (Racket's `read-char`) silently accept invalid utf-8?
1 point by akkartik 30 days ago | link | parent | on: 3-Dimensional Source Code

Is that a good thing, though? A classic design principle is that similar things should look similar and different things should look different. Imagine a project with both Flow and Project files. Wouldn't it be nice to be able to tell them apart at a glance?
2 points by breck 30 days ago | link | parent | on: 3-Dimensional Source Code

You are right, this is great feedback thanks.

> have a very confusing relationship to the coordinates

Agreed. I sometimes get confused too.

One rule that always holds is this:

  1) One line === One node
So every node has an absolute Y coordinate (just the line number), but also a relative coordinate(s), relative to its ancestor(s).

Both are useful at various times. There's probably a better way to eliminate confusion here.

> So the coordinates do not actually define the relationships between nodes

Given an array of node coordinates {y,x} [{1,1}, {2,2}, {3,1}, {4,2}], one has enough information to define the whole tree structure of the program. But you are right, you need the full set of coordinates of a certain node's ancestors to properly know its coordinates, and having a line that begins with 1 or more spaces, it is impossible to deduce how many nodes deep it is without also having access to the previous line(s).

2 points by breck 30 days ago | link | parent | on: 3-Dimensional Source Code

> An alternate syntax will not allow you to use any additional paradigms unless you also provide alternate semantics.

Right. The syntax for ETNs is the same, but the semantics are different. For example, I have a language called "Flow" that is a data flow language, passing a matrix through a series of nodes. I also have a logic language called "Project", that can solve relational issues among nodes. Different semantics, identical syntax.

Right now to use different paradigms, a user generally has to learn different semantics and different syntaxes. This eliminates the latter.


Not all binary sequences encode valid utf-8 characters.
2 points by shader 31 days ago | link | parent | on: 3-Dimensional Source Code

> Yes, there is semantic significance to adjacency & distance from the y-axis (which indicates an edge that connects parent and child nodes).

Actually, it seems like your tree relationships have a very confusing relationship to the coordinates. Adding a newline increments Y, and a space increments X, but children are those nodes such that that

  1) child.Y > parent.Y
  2) child.X == parent.X + 1
With additional complications that only the node with the lowest X value for a given Y becomes the child; all others on the same line become part of the content of that node.

This means that the relationships between two elements depends not just on their coordinates, but also the coordinates of nearby nodes. (6, 4) may or may not be a direct child of (5, 3); it depends on if (5, 3) is a full node, or just a content element that's actually part of (5, 2) or (5, 1).

So the coordinates do not actually define the relationships between nodes; they do not clearly relate to the tree structure at all.

2 points by shader 31 days ago | link | parent | on: 3-Dimensional Source Code

> this universal syntax could be big in that it can lead to better cross language static tools and enable developers who generally stick to one or two paradigms to make use of more.

An alternate syntax will not allow you to use any additional paradigms unless you also provide alternate semantics. It might enable more powerful editing tools or effective macros and metaprogramming though.


Readb and writeb work! Thanks so much!

I'm not sure why it doesn't work otherwise, but it points to something about interpreting the bytes as characters.


I just checked; it's not the first 0 byte.

Just to provide a little extra information, the image I'm testing with is my favicon: http://zck.me/favicon.ico


I don't know, this is strange...

Perhaps you could try using readb and writeb.


The files seem to diverge after a 0 byte. Can you check if it's the first 0 byte in the file?

Edit: never mind, I was hallucinating.

1 point by breck 34 days ago | link | parent | on: 3-Dimensional Source Code

> If there was semantic significance to adjacency or distance between points, or along each axis, that might be reasonable

Yes, there is semantic significance to adjacency & distance from the y-axis (which indicates an edge that connects parent and child nodes).

We are approaching everything simultaneously from the highest abstract level and lowest logical level. We have some more stuff coming out soon that shows off the benefits of the dimensionality more. One of the cooler experiments is a new type of processor with a graph-paper-esque 2D grid that can load a high level tree program and then execute it directly (no cumbersome series of transformations to a bunch of 64 bit registers). AFAIK this is original, though I wouldn't be surprised if Lisp Machines, Thinking Machines, Alteryx, Nvidia, Intel, et cetera have dabbled in this space a bit (though to date haven't been able to find anything on machines that execute trees directly).

1 point by breck 34 days ago | link | parent | on: 3-Dimensional Source Code

Thanks for the feedback!

> However, most of the work you have done is just a simplification of the syntax; it has no relation to the semantics whatsoever,

Agreed. However, I think one thing that is starting to emerge from our data (17 useful ETNs now compiling to Javascript, Rust, TypeScript, Logo, Haskell, C++, LLVM IR, SQL, HTML, CSS, JSON, and Regular Expressions) is how well this Tree Notation syntax can work for every programming paradigm (functional, imperative, declarative, dataflow, oo, logic, stack ...). Perhaps it is best explained as a universal syntax. The neat thing about this is that once you learn the TN syntax, you now know the complete syntax for languages with very different semantics. So while I agree we aren't changing semantics here yet, instead just leveraging the semantics and VMs of existing languages, this universal syntax could be big in that it can lead to better cross language static tools and enable developers who generally stick to one or two paradigms to make use of more.

> Perhaps the coolest part of your notation is the concept of constant validity

Agreed! The elimination of parse errors is one of my favorite features. Of course, the user can still make errors at the ETN level like mistyping a word or providing invalid parameters to a node. To help catch and fix these kinds of errors, I just launched version 5.0 of Ohayo (Ohayo still shitty, but the core is getting really solid) which includes a revamped compiler-compiler that supports 100% type checking of every word in your program. It makes it easy to create, as you say above "well defined input spaces".

More