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

We already have syntax in the form of bracketed functions (or whatever they're supposed to be called) and {} for tables.

I'm speaking out of my depth here, but I think it would be nice if scoped syntax extension were a "first class" feature of Arc. It would be nice to be able to load, say, native support for XML syntax as a library or something, or to easily extend the language through grammar definitions.

Also, infix notation in a Lisp? If I had a monocle I would drop it into my coffee with shock forthwith!

reply

1 point by akkartik 23 hours ago | link

Have you seen my proposal for infix syntax for Arc? I think it's pretty nice: http://arclanguage.org/item?id=16775. The big drawback: you have to give up '-' in symbol names.

reply

2 points by krapp 88 days ago | link | parent | on: Ask Arc: Arc forum RSS

There does already appear to be an RSS feed in the footer, but it doesn't appear to be sending the correct MIME-type so Firefox at least thinks it's just a malformed HTML page.

If I remember, I'll try to get it working later tonight since I'm messing with the stylesheets and HTML anyway.

Does anyone think a subscribe link to each thread would be a good idea?

-----

3 points by shader 87 days ago | link

I think a subscribe link for each thread would probably be overkill. Most threads don't last very long, especially since there's a time-limit on responses.

What exactly is it you're working on?

-----

3 points by krapp 87 days ago | link

>What exactly is it you're working on?

ATM, simplifying the HTML and CSS, removing obsolete tags (like font) where possible. Also eventually themes and having the base font size be selectable, since not everyone is comfortable reading 10pt grey on grey text.

-----

4 points by shader 85 days ago | link

Sounds good.

I guess these improvements will only affect people using the Anarki implementation of the forum? It would be nice if we could get some upgrades to the original arclanguage.org instance.

Specifically turning off the feature that disables replies on old threads, and probably switching to a most-recently-updated ordering scheme.

-----

2 points by krapp 96 days ago | link | parent | on: Noob resources for Arc/Anarki?

>"Package manager" means wildly different things and has wildly different responsibilities in different contexts and languages and platforms

I disagree. Most package managers for most languages share the same core functions and responsibilities: import and export code (likely from or to a repo), organize code into "packages" or "applications" according to some hierarchy, describe dependencies for packages using metadata and manage those dependencies when importing or updating.

The "special sauce" between them is in the way packages are defined and the metadata, and the way dependencies are handled, and those are details the Arc community could argue about until the heat death of the universe. But ~90% of what new people will want from Arc is to import News as an application or import libraries into their own local version of News.

-----

2 points by akkartik 89 days ago | link

Hmm, we've had this conversation a few times, and I think I may be unfairly holding others back. To reiterate the obvious, you should absolutely feel free to create a package manager in Anarki. The way you put it suggests it may not even be that much work for a rudimentary tool. Why not try it? Let a thousand flowers bloom :)

-----

2 points by krapp 88 days ago | link

>The way you put it suggests it may not even be that much work for a rudimentary tool.

From what little I know, it would be an exercise in suffering [0,1] and that's not even getting into arguments over how versioning should work. But I still want to do it... eventually.

I kind of suspect it would be pointless without some changes to the language itself which I don't know how to implement myself yet, and I don't want to just wait for other people to do the work. Basically, I don't think we can have useful packages until we can do something about the possibility of packages being able to globally redefine things and create unintended havoc. Namespaces would be nice too.

I am hoping to get something like plugins working in the forum, though. I've already combined the repo and what was the plugin manager and I've been trying to get hooks to work through it so that it would be possible to 'plug' scripts in or out of those hooks during runtime. It might also be useful as a way to add updates by hotpatching the existing code (which is really the only valid use I can even think of for being able to redefine things in Arc.)

Maybe, if that ever gets anywhere, something like a package manager can emerge from it.

[0]https://medium.com/@sdboyer/so-you-want-to-write-a-package-m...

[1]https://news.ycombinator.com/item?id=11088125

-----

3 points by shader 87 days ago | link

I'm actually somewhat intrigued with the idea of using guix[0] as a language package manager. It has really nice facilities for setting up "environments" that contain a set of packages, so you can use it for bundling together all of the deps needed to build a particular application. As a bonus, it uses scheme as its configuration language :)

It wouldn't solve arc side of actually loading packages, which probably still needs work, but it should work pretty well at managing them.

____

[0] https://www.gnu.org/software/guix/

-----


relevant HN thread: https://news.ycombinator.com/item?id=19430840

-----

3 points by krapp 128 days ago | link | parent | on: Noob resources for Arc/Anarki?

>I install packages (although I think the only ones I use are ones I've created) by downloading the file, then calling `(load "/path/to/file")`.

To be fair, though... when most people say they want to "browse and install packages" for a language, they don't mean including local files through a REPL. Although that is the best we can do in Arc for now.

-----

3 points by krapp 142 days ago | link | parent | on: Noob resources for Arc/Anarki?

In Windows, the install instructions in the readme should work. You may or may not have to set environment variables, I don't remember if I had to do that, but I don't remember having any issues. You'll probably want Git and MinGW as well.

If by "browse and install packages" you mean for Arc, you can't, yet.

I use Sublime Text with the syntax set to Lisp (which works well enough) and the terminal plugin, so I can open a Powershell prompt with Ctrl-Alt-T.

-----

2 points by nupa 142 days ago | link

Thanks for the advice! I figured I was just missing something, but if it doesn't exist yet then that's reasonable enough.

I've heard of foreign function interfaces, does Arc have one of those?

Regardless, I'm sort of getting the impression that Arc is something I should come back to someday when I'm able to contribute tooling to it -- it's an amazing core but not much else.

-----

2 points by krapp 142 days ago | link

>I've heard of foreign function interfaces, does Arc have one of those?

If Racket interop counts, then yes, albeit not seamlessly.

>it's an amazing core but not much else.

Yeah, it's mostly News and some random experiments. Fun to mess around with, though.

-----


Just in case anyone might care, the current version of news deprecates npage and the subpage templates for a single layout macro and no longer uses the table layout, so that all news pages have a consistent look and navigation. I'll get around to finishing my vague plans to clean up and update the HTML eventually, since there are still some inline styles and font color tags and such that need to be gotten rid of.

Also, there's no longer any (gen-css-url) or votejs*, those have been moved entirely to external js and css files (except for the topbar color.)

Also eventually, I'm hoping to separate the layout stylesheet from the color stylesheet so that the latter can be swapped out as themes.

[0]https://github.com/arclanguage/anarki/blob/master/apps/news/...

-----

2 points by krapp 151 days ago | link | parent | on: Variables & scoping complaint

>So you could have lib#1 set var 'x' only for it to get clobbered by lib#2's version of var 'x' and arc just ignores this. That's bad. Really bad.

And how often is it intended behavior? How often does one want to have a macro parameter or apparently "local" variable overwrite an existing symbol globally and arbitrarily?

I can see it being useful in the case of "hot patching" code to just redefine a function, but that's still kind of crazy, since now the source code and running code are no longer the same. Might as well just edit the file and reload it, and have one source of truth.

It seems like an anti-feature. Something that seemed like a good idea in theory, but which in practice does more harm than good.

-----

2 points by akkartik 150 days ago | link

I'm not following the two of you on precisely what this anti-feature is. Assigning to local variables using '=' does not create new global variables. Can you share a code sample showing what you're talking about?

-----

1 point by i4cu 150 days ago | link

> Assigning to local variables using '=' does not create new global variables.

We're referring to the original posts problem where using = inside a function can redefine global variables:

  arc> (= data* '(green red)) 

  arc> (def my-fn () (= data* nil))
  #<procedure: my-fn>
  arc> (my-fn)
  nil
  arc> data*
  nil
Now my comment was referring a bigger problem that falls out of this 'feature' or 'anti-feature' (depending on your point of view).

assume you place this in html.arc

  (= data* '(blue red))

  ; (add-color 'purple)
  (def add-color (color)
    (push color data*))
    
Then I create apple tracker library 'lib/apples.arc' with:

  (= data* '(green red))

  ; (add-apple 'golden)
  (def add-apple (color)
    (push color data*))
Now at the top level of my progam:

  (load "lib/apples.arc")
  (load "lib/html.arc")
; now say the first apple in storage has gone brown:

  > (string (car data*) " has gone brown")

  "blue has gone brown"
say what? my blue apple has gone brown?

why is there no warning or error on loading my lib? That's pretty bad IMO.

-----

3 points by krapp 151 days ago | link | parent | on: Variables & scoping complaint

Yeah, as a newcomer I can attest that I did not know that. V here being global is really counter-intuitive:

  (defun f ()
     (= v 10)
     ...)
I would have expected (and would prefer) the default to be to bind to whatever the current scope is, and to have global (file level, then application level) scope be opt-in rather than opt-out. We can't assume that it's more likely new users will be familiar with lisp idioms.

-----

2 points by rocketnia 149 days ago | link

In your example, the variables in scope inside `f` are exactly the same as the variables in scope outside of it. You're implying the "current scope" has changed, but if the set of variables in scope hasn't changed, then what other part has?

I think you were expecting a concept that Arc doesn't have. Adding an unnecessary concept to Arc would make the language more complicated for newcomers who weren't expecting it, right?

Of course, if users do consistently come in with the same intuition, it's pointless to design against it. Often we've gotta design for complex realities rather than simple principles. :) If you think it's a case like that, I can sympathize, and maybe someday I'll see it.

Sometimes I feel like general-purpose plain text programming language is such a specific topic that it leads to only one possible language design. Feeling that way is probably the only way I'll design a single language at all, rather than designing a lot of half-languages and never finishing any of them!

In this case, I actually _don't_ feel like there's _no_ potential to alternative notions of lexical scope or variable assignment, but I think Arc's at a sweet spot, and I've some extensive reasoning as to why....

---

"We can't assume that it's more likely new users will be familiar with lisp idioms."

If not some other language's idioms, where did you get the idea of there being a "current scope"?

It's true that many popular languages have features where they infer a variable declaration at some notion of "current scope" around innermost point (Python) or outermost point (CoffeeScript, Ruby, MATLAB) where a variable is assigned. Newcomers to Arc from to those languages might expect this. (I think uu must be bringing in Python experience.)

I think some languages (R, Kernel, maybe some Scheme interpreters) represent the lexical scope as a run time data structure, and variable assignments can add new variables to the local scope that were previously looked up from an outer scope. They have lexical scope, but arguably not static scope.

I also want to mention PHP, which is off doing its own thing where there's hardly any implicit inheritance between lexical scopes at all. Every variable lookup or assignment is restricted to the current function unless there's an explicit `use` or `global` declaration to imply otherwise. I kind of admire PHP's willingness to make the interaction between scopes explicit like this; it means PHP could evolve to have different parts of the code written in different languages, with explicit marshalling of values between all of them.

Newcomers coming in from any of these languages might have different expectations. And that's not to mention newcomers from JavaScript, Perl, Scheme, Common Lisp, Clojure, Erlang, Haskell, Elm, Java, C#, etc., who probably expect Arc's scoping to work exactly as it already does (or who raise completely unrelated issues, like objections to Arc's unhygienic macros :-p ).

So let's look at Arc as its own language.

Thanks to Arc's lexically scoped `fn`, it's basically an extension of the lambda calculus, and it has easy access to all known lambda calculus techniques for Turing-complete computation. This means Arc programmers basically don't have to use assignment at all unless they want to.

In Python, those lambda calculus techniques are possible to use in theory, but every nontrivial lambda must be named and pulled out onto its own line, giving us something a lot like `goto` label spaghetti.

In PHP, every nontrivial lambda must have a `use` declaration to pull in all the variables it captures. This can get to be particularly verbose, eventually to the point where it might be easier to pass around explicit context objects.

Even using lambda calculus techniques a little bit in Python or PHP means we start to have trouble with mutable variables. Lambda calculus uses functions for control flow, but using functions in Python or PHP means creating new scopes, which means we can't easily assign to outer variables from inside our conditionals and loops. Most uses of mutable variables involve some kind of conditional or loop (or variable capture for its own sake), since that's what makes them anything more than a sequence of variables that happen to share the same name. So the more we use lambda-calculus-style conditionals and loops, the less we effectively have access to mutable variables in the programs we're writing.

In both Python and PHP, it just takes a little more boilerplate to work around this: We give up on mutable variables altogether and simulate them with immutable variables that refer to mutable objects. (There's also `use (&$foo)` in PHP and `nonlocal foo` in Python, if you prefer not to give up on mutable variables, but they amount to far more boilerplate.)

The standard boilerplate for these things in Arc is pretty much less than zero, thanks to macros. An Arc programmer can write a custom conditional operator as a higher-order function, and then when they're tired of putting the conditional branches in `fn` every time they use it, they can write a macro that generates the `fn` automatically.

Since Scheme and Common Lisp were already well-worn combinations of lexically scoped `lambda`, mutation (`set!`/`setq`), and macros, all of this could pretty much be predicted when Arc was designed.

Nevertheless (or maybe out of having different goals than I'm expressing here), Paul Graham and co. tried out automatic local variables anyway. It was implemented for an early, unreleased version of Arc.[1] Then they pulled this feature out because they realized they kept introducing or removing lexical contours by mistake and breaking parts of their code.[2] I bet this is because they were implementing some of their control flow macros in terms of `fn`.

Could it be possible to follow through on their experiment without recognizing all the same mistakes and pulling the plug again? Yes, I bet it is.[3]

But I think Arc's local variable scoping rules and variable assignment behavior are exactly what they need to be:

- Implicit inheritance of lexical scope to enable lambda calculus techniques (unlike PHP).

- The easy ability to mutate variables in outer scopes so mutation can work together with lambda-calculus-style control flow (unlike Python, R, and Kernel).

This still leaves the CoffeeScript/Ruby/MATLAB approach on the table, where only the outermost assignment is treated as a declaration. I don't particularly like this approach, and that's because I prefer for the outermost level to be relatively seamless with the rest of the language. That way it's easier to break parts of the language off into optional libraries when it turns out they're not as helpful as expected. Arc's top level already isn't seamless with the rest of the language, but I think this would be a step in the wrong direction.

In summary: If users come in with incorrect ideas about Arc's variable assignment behavior based on their experience with other languages, I think that's most likely a place where other languages could learn something from Arc rather than the other way around. The higher-order techniques of lambda calculus are a sweet spot in language design, and Arc's system for local variable scope is well tailored to that. The Arc designers originally did try automatic local variables. They found them to be unnecessarily complex to work with, and I agree.

---

[1] http://www.paulgraham.com/arcll1.html "Here is a big difference between Arc and previous Lisps: local variables can be created implicitly by assigning them a value. If you do an assignment to a variable that doesn't already exist, you thereby create a lexical variable that lasts for the rest of the block. (Yes, we know this will make the code hard to compile, but we're going to try.)"

[2] http://paulgraham.com/arclessons.html "In Arc we were planning to let users declare local variables implicitly, just by assigning values to them. This turns out not to work, and the problem comes from an unforeseen quarter: macros. [...] In a language with implicit local variables and macros, you're always tripping over unexpected lexical contours. You don't want to create new lexical contours without announcing it. [...] It seemed to us a bad idea to have a feature so fragile that its own implementors couldn't use it properly. So no more implicit local variables."

[3] In Racket, the `racket/splicing` module (https://docs.racket-lang.org/reference/splicing.html) has a few rough edges, but it's a good example of how the choice of whether a macro changes the "current scope" can be controlled deliberately, even in a language with lambdas and macros. I didn't bring up Racket or Scheme's notion of "current scope" with all the other examples because it doesn't interact with variable assignment, but I think even that notion is a kind of ill-conceived complexity that I'm glad Arc doesn't have. It's handy to have local syntax that roughly resembles the top level to aid in refactoring, but on the one hand the resemblance isn't required to be perfect (and isn't perfect in Racket), and on the other hand the Scheme top level isn't very easy to make modular, so it's not even a good thing to resemble.

-----

2 points by rocketnia 146 days ago | link

Oh, right, here's another reason I don't like the CoffeeScript/Ruby/MATLAB approach where a variable is declared automatically at the outermost point where it's assigned: I like to be able to declare local variables that shadow variables from outer scopes. When `=` declares non-shadowing variables only (since the rest of the time it acts as an assignment rather than a declaration), shadowing is more cumbersome to do.

-----

2 points by rain1 149 days ago | link

point [2] sounds like a problem of non-hygienic macros. perhaps it can be reconsidered now that there's syntax objects.

-----


why not go all the way and render client-side in a canvas as well?

As it is, the more "pixels" you have, the slower the page loads. You could probably have just a single canvas and a single event handler.

You could preserve functionality for non-js users by using an imagemap (assuming browsers still even support those) or sticking the existing code in noscript tags.

-----

2 points by krapp 156 days ago | link

OK... I don't know where I got "single event handler from," that obviously wouldn't be true, but it would still be simpler than having each pixel be a separate HTML form....

-----

1 point by shawn 156 days ago | link

Wanna hop into discord and we can chat about the design? https://discord.gg/qaqkc9z

The repo's open, and I could help get you set up with it if you wanted to work on some of this. https://github.com/laarc/laarc

It should be a matter of:

  git clone https://github.com/laarc/laarc
  cd laarc
  make
  rlwrap bin/arc
  ((load "news.arc"))
and then http://localhost:8080/place

-----

2 points by krapp 156 days ago | link

Let me actually see if I can come up with a POC first, at least for the canvas and javascript. Realistically, since it's just GET requests that don't need authentication, I shouldn't even need laarc running, I can just send the same requests by AJAX.

-----

2 points by shawn 156 days ago | link

https://www.laarc.io/place.json is the API, by the way! I should probably mention that somewhere.

-----

More