Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: ScrapScript – A tiny functional language for sharable software (scrapscript.org)
503 points by surprisetalk on April 27, 2023 | hide | past | favorite | 135 comments
Hi friends,

I started casually working on scrapscript in 2015. I built a few compilers over the years to test out various ideas/implementations, and I think I'm finally happy with the overall design.

The code is not public yet. Email me at hello@taylor.town if you're interested in joining the core team later this year.

Let me know if you have any questions or feedback :)




So it's like a social network with every type of relationship imaginable built into a low level programming language?

That's wildly cool.

This and Val Town [0] feel like they were made for each other. If you added them together with a nice front-end like mmm.page [1] I bet a million devs would sign up.

I'm working on something in a similar space that I'm hoping mihht develop into that [2]

It makes sense that the next step for the web is a more low-level social platform that works more like an agnostic API than a walled garden.

[0] https://www.val.town/

[1] https://build.mmm.page/

[2] https://hyperspace.so/


Wow, you totally get my vision!

This is pretty much my plan for the next few years, with some added surprises :)

I really want to rekindle the days of geocities and flash. I call this "the cheap web" haha

I've also been working on open standards for authentication and payments within the ecosystem, but I'm not quite happy with the results yet. I don't like this world where we have to use companies like Auth0 and Stripe to build something worthwhile. I'm open to ideas!


You should look into https://small-tech.org/. I don't know if they're still active (I discovered them a few months ago, and they seemed active.) But they definitely have a similar point of view.


They are active. You can follow Aral Balkan [0] and Laura Kalbag [1] on the Fediverse. Aral is building a range of small-tech goodies, like Kitten [2], a small web development kit. And they are starting their 'Small is Beautiful' [3] livestreams again, using Owncast.

[0] https://mastodon.ar.al/@aral

[1] https://mastodon.laurakalbag.com/@laura

[2] https://codeberg.org/kitten

[3] https://owncast.small-web.org/


Use some type of cryptocurrency for payments, or maybe a unified interface to different cryptocurrencies.

Or maybe you can come up with something similar to a cryptocurrency that integrates with your data structure and has core things like digital signatures for secure transactions and public distributed ledger(s). It seems like there could be a way to adapt some underlying features of ScrapScript for this stuff. Maybe as part of the "lab" thing.

Just don't call it a cryptocurrency. Lol.


Why inject money into everything? I don't remember the cheap web being focused on micro transactions and ponzi schemes. That's the opposite of what the author (and many others) want.


Exactly. Throw "cryptocurrency" into anything you want to spoil and witness the dynamics of greed ruin the fruits of your labour.


Heyyo. Creator of mmm.page here. Fun to see it mentioned. In case it's of interest, I've been coming at this from a more GUI perspective: scriptable objects (like paper) [1] and social primitives [2].

Excited to see where this project goes.

[1] https://paper.mmm.dev/

[2] https://twitter.com/xhfloz/status/1611094168981458981


Author here.

The more I dig into mmm.page, the more I'm loving what you've built! I can't wait to play around with it next week. The design is gorgeous so far.

Somebody is giving a talk on "Print Inspired People-Computing" at my tech conference this August. You two would probably get along pretty well!

I'd love to have you in our community, so feel free to email me at taylor@outland.sh and I'll send you a free ticket :)

[1] https://outland.sh


Oh, amazing! I am planning my travels for this year -- I just might :) And thank you for the kind words.


The signal to noise ratio in your comment is off-the-charts awesome – thank you for the amazing links!!


Thank you I've been trying to find the build.mmm.page link again for a year but I couldn't remember the name of the site XD


Thanks for these links. Looks like I have a new rabbit hole to explore!

Side note: I was just watching the val.town video and at the end he mentions that "you are an object" and other people can access your properties. It immediately made me think of playing hackmud. Not sure if that's a good thing or bad!


> https://build.mmm.page/

The stuff there looks like a "MySpace 2.0".

And that's not a compliment.


Are you kidding? This is a bonanza!!!


Maybe. But only if you like 90's web with blinking GIFs all over the place.

I'm grown out of it.


One fundamental design principle of mine has been to be minimally prescriptive with the interface of mmm.page, so that people can create whatever they want. If that means 90s throwback, then I won't go out of my way to prevent that.

That being said, I have my thoughts on nostalgia-mining [1], and in short, believe that a more interesting visual culture today requires a more contemporary approach.

For example, one of my favorite pages is a page of hand-drawn comics combined with GIFs made by a kid [2], another is a cleverly-designed page on "soft tech" [3]. Here is an illustrative thread comparing link-in-bios and mmm.page sites made by the same person -- it's surprising how much tools can limit our self-expression [4].

Personally, I get excited when I see these examples -- a departure from the grid-confines of contemporary web design. In theory, nothing about "letting people create pages with as much freedom as possible" intrinsically = "90s web with blinking GIFs all over".

Let me know if you have any other questions.

[1] https://twitter.com/xhfloz/status/1631746051295117313

[2] https://littlebookfair.mmm.page/oneoneone

[3] https://helena.mmm.page/soft_tech

[4] https://twitter.com/xhfloz/status/1649508702523645956


Reminds me of what unison already does, I just wonder what will be license and scope

https://www.unison-lang.org/


I'm still not sure about the exact license yet, but everything will definitely be free and open :)


In your styles:

> pre { overflow-x: scroll; }

`overflow: scroll` is very poorly named, and practically never the right tool. You want `overflow: auto` instead, which only renders scrollbars if they’re needed.

(Long ago, there were two potentially valid scenarios for it: for avoiding reflow when changing the document’s length, and for unbreaking viewport units so that 100vw includes the viewport’s vertical scrollbar. The former was only exceedingly rarely useful, and can be achieved better now on all but Safari with the scrollbar-gutter property. The latter only Firefox ever implemented, and no one else wanted to, so they eventually removed it from the spec and from Firefox, so now viewport units are just stupidly broken by design. I myself have not found a single place I wanted to use `overflow: scroll` or where it would have been reasonable in the past decade. Stylesheet linters should include a default rule that complains about `overflow: scroll` because it’s so temptingly-named but so thoroughly not what you want.)


It’s the right tool when you prefer scrollbars to always be rendered, which is a valid preference. For example, in the “not needed” case, the scrollbar being rendered tells you at a glance that there’s no scrollable content with a hidden “only appears upon movement” scrollbar, an information which would otherwise be missing.


I’m completely confused by what you write, because it seems back-to-front. You seem to be speaking of platforms with overlay scrollbars that are invisible until you try scrolling; how does `overflow: scroll` behave differently from `overflow: auto` on such platforms? I would expect it to either be no different, or possibly to briefly show a completely misleading scrollbar briefly when the content appears. I think I must be missing something. Can you explain more what you mean?


It's late and I'm tired but this is one of the most interesting things I've seen in a while.


Would the IPFS-ness of this make updating all the programs that suffer from an exploit or error a difficult thing? Kind of like smart contracts, once it is published, there is no changing it? So the chain of dependencies containing the exploit or error, make updating all of the consumers a pain.


This is a great observation.

By default, using a name like `janedoe91/fibonacci` pulls the latest version of that particular scrap from the scrapyard. But all of its references are baked-in unless the author updates them.

The way around this is that consumers are empowered to use whatever forcing upgrade strategies they want. All scraps are transparent, so you can pipe everything through an "upgrader" scrap before execution, which replaces dependencies all the way down the stack with their latest versions. I'm sure many of these upgraders will exist depending on what types of tradeoffs you're looking for.


Can scraps be versioned? Is it possible to see the available versions of a scrap? Could you add support for dependency management?

MVS is a nice and easy algo: https://research.swtch.com/vgo-mvs


Yes, scraps can be versioned:

  user/my-scrap@99
And you can check the available versions of the scrap by querying the scrapyard directly. But omitting the version will just use the latest:

  user/my-scrap
Each scrap contains a full list of its own dependencies, so there is no need for external dependency management.

All scraps are transparent, so you can create your own tools to manually tweak/replace dependencies before execution:

  $ cat my-scrap.ss \
    | scrap apply my-dependency-helper \
    | scrap eval


This fixer would have to walk the dependency tree. What if something breaks contract in the middle, something I do not control? That sounds like a huge burden on developers with lots of risk.

Why opt out of proper dependency management?


You can emulate traditional dependency management by pinning the versions of all your scraps, and updating them selectively:

  user/my-scrap@414
> This fixer would have to walk the dependency tree.

Remember that the language itself works like a merkle tree and every scrap can be cached anywhere. To keep the language and tooling extremely simple, I think this works well enough.

> What if something breaks contract in the middle, something I do not control?

Everything is strongly typed, so there are certain guarantees about how things can break and update. You can easily make tooling that never makes breaking changes.

People can always introduce implementation bugs into their code though, but that's inevitable even with dependency management.

> That sounds like a huge burden on developers with lots of risk.

I will try my hardest to reduce that burden. I think I can put some sane defaults in the tooling surrounding the language to obviate the need for traditional dependency management.


So the issue is see with lack of dep management...

1. My code depends on dep A and B, which also depends on A.

2. A has some issue, so I update my reference, but B does not.

3. Given dependencies are bundled, B still contains the bad A.

So how can I updated the A used by B? (Without effectively forking B) This is more a problem with bundled or censored dependencies than the lack of dependency management. Dep Mgmt aims to solve this issue by having only one copy of a dependency


Except in many dep management systems they purposefully don’t keep only one copy to allow multi versions to run side by side and other benefits like having a deliberate piece by piece upgrade of everything in the dependency tree. Forcing all deps to be on the same version of all other deps sounds like it would cause more problems than it would solve.

Also the ideas of immutable deps mean this property of “duplicated” deps comes naturally.

I think many bugs can come from what you propose. A large dev tree would need everyone in the tree to coordinate to upgrade all at once. That seems basically impossible for any dep tree. Especially in a system where the deps are small code snippets like this one. Even small programs can have 1000s of deps.

Why are you implying that this model is “normal” dep management?


Aka “the diamond dependency problem”.

If the “old” A has a severe vulnerability and the “new” A has breaking changes - then there is no solution other than to avoid/replace/fork B until B is upgraded.


I like the unique hash thing like Unison, but it also has an Urbit/Nock/Hoon vibe aside from IPFS one you mentioned. I'll check it out tomorrow. Ilike the examples and syntax. Types - yay!


Why the custom language? Building a language is already a lifetime project on its own

As I see it most of the more unique ideas could be implemented in form of some tooling on top of some existing languages.

What do I overlook here?


> As I see it most of the more unique ideas could be implemented in form of some tooling on top of some existing languages.

I deeply hope that's true, because it'll save me a lot of work :)

Software doesn't seem to be getting better. In fact, it seems to be getting worse in many areas.

Personally, I don't think there's "one big thing" that harms the ecosystem. I think it's friction in 1000 different places due to systems that don't quite work together seamlessly.

Scrapscript is an attempt to vertically integrate all the lessons we've learned in software in the past 80 years.


everyone says this is cool, but I didn't understand it at all, so embarrassing :(( please eli5, honestly, want to understand this, what is this and how is it useful?


One cool thing, I think, is that you can do

import foo/bar

And foo's bar library will just work in your program without you having to download it then bundle it. It will just look for foo’s bar library online when it runs (and I guess it’ll be running on an online platform, not necessarily on your own computer).


Sounds quite dangerous...


It's only dangerous in very predictable circumstances :)

Type-safety guarantees that you won't get any side-effects where the types don't fit.

And if you really want to run untrusted code, scraps are designed to be very easy to inspect :)


Author of a framework that also stores it's code in IPFS for easy sharing (https://github.com/yazz/yazz). ScrapScript is a really nice concept with how it stores code. I originally got the idea for storing the code as a hash of the contents from Unison, and it looks like the idea is really starting to catch on with more and more languages now. Well done!


This is lovely. I’ve had a vague notion that I wanted something like this… but never quite solidified my understanding of what is necessary. This is a super minimal-maximal example. Bravo.

Do equivalent programs produce the same hash?

Ie: a = 1 + 1 Return a

Vs

a = 2 Return a

What if local internal variable names change?

Ie

b = 2 Return b


This is one great question I've wrestled with over the years.

Right now, all three programs would result in a different hash. I decided that the scrapyard publication process should do as little "magic" as possible.

As the tooling evolves, we can provide a canonicalizer scrap that renames variables and simplifies the code. I think eventually we would make this the default process to encourage more reuse.


You might want to look into the way Unison does things: [1], they've got a lot of similar ideas and IIRC the way their hash system works avoids that ambiguity.

[1]: https://www.unison-lang.org/learn/the-big-idea/


Wow, that's a great guide!

I didn't read it in-depth yet, but I think I had a previous implementation that worked very similarly to theirs.

The problem with variable names is that they actually matter for some of the collaborative editor features I hope to implement in the future. There are certain assumptions I can't make quite yet, and so am keeping my options open :)


Have you thought about using type aliases or higher order types of some sort for that instead of relying on the variable name?

I could define that a familyname and a givenname are strings, and then a function argument of type familyname would be differentiated from a function argument of type givenname, but still the argument names themselves could be dropped from the hash.


Thinking a bit more:

A-If a program is a thing that produces a result for a given input, these programs are the same.

B-You can’t generally know if two programs are the same without solving halting problems, reducing polynomial algos to linear time or having infinite time and space computing resources, etc.

C-The best you can do is ask if two compilers produce the same output, or a linting/refactoring/canonicalization/formatting operation results in same source.

D-If a program is a thing that interactive debuggers use to create explorations next to source code while computing, these programs are different.

I agree with your approach of starting with these programs as being different, and allowing custom scraps to become a higher layer hash resolver. The reason is that compilers change over time, and it is only under the lens of a compiler(or linter, etc) that comparisons can be made. To bake a holy compiler in today would be arbitrary and quickly outdated.


Due to the halting problem, it's not possible to tell in general if two programs are equivalent.


As far as I know, nobody ever proved that some programs for which halting cannot be determined are smaller in size than the number of atoms in the universe. Or in other words, that the theorem applies to practical programs. It's purely theoretical.


Here is a Python program which is definitely smaller than the number of atoms in the universe. Can you tell me whether it halts?

  n = 1
  while sum(d for d in range(1,n) if n % d == 0) != n:
      n += 2


Oh this is a good one. It halts if there’s an odd perfect number, right?


Yup.


If I can't then that's no proof that the halting theorem is true for practical programs.


If it's so hard even for such a simple program to determine whether it halts, why do you expect it to not be a problem for much more complex programs?


It absolutely is a problem. But don't say that there is no solution to it unless you have a proof.

I'd be impressed if you gave me a program for which it provably cannot be proved that (edit: if) it halts. Or a bound on its size.


> I'd be impressed if you gave me a program for which it provably cannot be proved that it halts. Or a bound on its size.

For every program that halts, it's obviously possible to prove that it halts. The point is that there is no algorithm for deciding if an arbitrary given program halts.


> there is no algorithm for deciding if an arbitrary given program halts.

But can you prove that statement if I change it into:

there is no algorithm for deciding if an arbitrary given program with size less than N halts; for some suitable definition of size.


Since we're considering practicality, let's change the statement to: “There is no algorithm for deciding if an arbitrary given program with size less than 1000 bytes halts which can be implemented without solving several famous open mathematical problems”. I think my program pretty clearly shows that this is true.


[never mind, misread the conditiom]


Why? This gives sum([]) != 1, which is true. Have you actually tried running the program?


Hello!

This looks really interesting to me.

There is a feature I would like that I have never seen in a scripting language, and I wonder if Scrap might support it:

> Monadic bind points and applicative join points in the script language

Hopefully an example can convey what I mean.

Bind:

    do {
      let! x = some_value_in_a_monad

      x + 1
    }
Applicative:

    do {
      let! x = some_value_in_a_monad
      and! y = another_value_in_a_monad

      (x + y) * y
    }
Now when I embed this script, I would like my runtime interpreter to provide implementations of `let!` and `and!`. The script author defines the bind points and the runtime defines the effects.

Is this possible in Scrap?


OCaml has a similar thing but purely on syntactic level — http://jobjo.github.io//2019/04/24/ocaml-has-some-new-shiny-...


Stricly speaking, F# can be used in scripts too, which is where I think you've taken that syntax from. Ionide however is quite broken when writing scripts (or anything else) though.


Wow, I really like that syntax!

Juggling lots of monads can be annoying. But to keep scrapscript small like json, this is something I would try to solve with editor tools rather than the language itself.


How should users write async, futures, option, result, etc. in Scrap?

My hunch is that if you do not put the syntax into the language, then it will be hard for the community to standardize on one preprocessing tool.

OCaml (which I am a fan of!) struggles with fragmentation here.


With managed effects, all of the async stuff gets pushed over to the platform.

I suspect that everybody will settle on a reusable `task` type, but each platform can determine its own async scheduling system.

Consider this example:

  | "/home" -> q -> res:success <| "<p>howdy " ++ name ++ "</p>"
    , name = q |> dict/get "name" |> maybe/default "partner"
  | "/contact" -> _ -> res:success "<a href="mailto:hello@example.com">email</a>"
  | _ -> _ -> res:notfound "<p>not found</p>"
  . res = : success text : notfound text
In this case, the platform creates a simple web server from the following type:

  text => query => res
  . res = : success text : notfound text
Because scrapscript stays out of the scheduling game, the platform is free to run this code on as many cores and servers as it wants in parallel.

But I 100% agree that community standardization is incredibly important! I just don't have a solution yet :) I will try my best to get everybody to work together though haha


This is significant. There's so much I want to add, but I will wait until I can implement the things I needed this for in the actual code.


I'm trying to wrap my head around the "magic compression" bit. So literally every namespace lives in a repo somewhere? And even files referenced are just automatically committed to that repository? What am I missing?

Also how does this not create either an enormous tangle of circular references or a huge pile of unused... scrap?


It’s content addressed, so circular references can’t naturally arise. You kind of need to create an ID of some sort and reference that and create some way of looking that up. I didn’t check if they allow for recursive function calls, etc.

The repository/scrap pile of content could be stored in lots of ways that you could choose. I imagine if everyone pushed directly to a global “scrap pile” like IPFS it would end up as a huge pile of unused scrap. Like unison, they’d need to provide some kind of default development environment, but anyone could build additional tooling (kind of like anyone could write a git clone).


This is very cool. I have similar goals with my own language. Though I am developing only and AST and no syntax because I would like to be able to embed the same language into visual programming environments.

https://petersaxton.uk/log/


Since each function is independently versioned, how does ScrapScript deal with functions that need to upgrade together?

For instance, suppose "foo" produces a structure and "bar" consumes it - what happens if the user passes the output of "foo version 10" to "bar version 1"?


If the function output remains the same, then there are no breaking changes.

If breaking changes occur, the type system will let you know :) Then you can either pin the function to an older version or fix the breaking changes directly.

The language provides enough guarantees to make tooling that can handle most of this for the user automatically.


Very interesting! I'm especially curious on how the live-coding experience plays out.

I wish there was an example of a moderately-complex scrapbook, so that I could see what the code looks like when you start mixing several scraps and need a minimum of scaffolding.


This is fantastic. I can't count the number of hours I've wasted hacking away broken CI pipelines to fix broken links, passing data around through environment variables sorcery, runners and artifacts wizardry.


One question. If you reference a package by hash. Is there semantic versioning? Can you get security updates?


I'm currently planning non-semantic versioning (next versions just increment by 1), but I'm open to changing if I can figure out how to make semver efficient.

I mention it here[1], but security updates can be performed by both authors and consumers.

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


I am not a super fan of semantic versioning (but it is "OK").

What I like is you can flag "breaking" vs "enhancement" vs "no api change". And "no api change" is usually always what you get with a security patch.

Really you only need 2 versions in semantic version (my opinion): breaking.non-braking

"next versions just increment by 1" might be good where you have a non-breaking change, and that would allow security patches to flow down.


Not 100% sure but there is another project with similar ideas https://www.unison-lang.org/


I don't get it. Can someone use an example to demonstrate the value of this?


Just think of it as more powerful JSON :)

You can send things around without converting everything into strings and objects that don't quite fit your use-case. Plus you have the added benefit of strong typing AND the ability to send those types to other systems.

Most of the other features exist to make it nicer to use as a full programming language.


This is perhaps too bright for the gloom of recent months here.

Thanks to the author, this is a very exciting thing.

Of course, ligatures without the "disable ligature under a cursor" extension are slightly weird, but it even adds charm, we're on a site "for hackers" (laughing).

So, well, what kind of a ChatGPT can come up with something like that? :)


This is incredible. I’ve been thinking a lot about personal software systems and a hypothesis that I have is that simpler code sharing/versioning mechanisms is key to greater agency in programming environments. I’m already a huge fan of unison (we had Rúnar on devtoolsfm) so I’m eager to explore scrap further.


Neat but... Someone will make a crummier version of this in a language which doesn't feature parts looking like Unicode white noise and the original authors will be frustrated why the crummier vetsion took off and their project didn't.

Not every idea deserves to have an esoteric language attached to it to work.


The funny Unicode symbols are actually ASCII `->` and `|>` rendered in a font with ligatures. I agree it's a bit jarring to see, but you wouldn't need a special keyboard.


This really should be mentioned on the page. My first impression was: "well, however cool this is, I will never use it because I can't just type it in any terminal without creating some stupid bespoke environment for it".

EDIT: I just copied and pasted a code example into a text window and the raw typed text is exposed. Maybe something like a suggestion to do that could be included for anyone flummoxed by the symbols?


The font is Fira Code for anybody interested!


JetBrains Mono does that ligature `|>` in my Elixir code. I like it :)


Ohh… totally missed that!


Yeah, the language and ideas are so cool they're nearly a whoosh for my old brain. But I will never understand why anyone would go out of their way to present a programming language while obscuring how you actually type it.

I had to copy-paste the "weird-looking play-symbol" (|>) into a text editor to see if it really was what I thought it was [1], after noticing that selecting it with the mouse split it in half. That is highly distracting from the message, at least to me.

[1]: It was.


I’ve been using fonts with ligatures for esoteric languages like CSS and HTML for years. ;-)

Seriously, fonts that coders tend to use have included ligatures for quite a few years. For me, it’s less visual noise and a cleaner look.

I use Vim/Neovim and WezTerm but there are many combinations of editors and terminal emulators that support ligatures.

And many programmers fonts: https://github.com/ryanoasis/nerd-fonts


I’ve been working on a crummier version. So crummy it will likely never make it to a v0.1… :)


Looks fun, but doesn't look like it will be open source. That's a shame, since it considerably raises the risk of adopting such a platform.

EDIT: the author claims that it will be open sourced soon :)


Author here! It will be open sourced soon, but I’m embarrassed about my messy code :)

Email me at hello@taylor.town if you’re interested in joining the team


A rule of thumb is that if you're not embarrassed when you launch, you've waited too long.


No one really checks out old commits though. And any employee who cares about anything open source being “bad” isn’t worth working for.


What is the plan for 2024 and what are the goals for the core team right now. I would potentially be interested in joining.


My next step is to release an airtight spec and roadmap to all the people that are interested in contributing. I'm receiving a ton of emails from devs who want to contribute but don't have experience in compilers, so I'd like to find a way to evolve the system in a way that works for everybody.

I think first steps with the core team would be to source feedback on some of my design and architecture decisions. It'll be much easier to build everything if everybody shares the same vision and we're aware of all the tradeoffs.


Fuck It Ship It


What are you building it in?


My latest iteration uses a bootstrapped compiler written in scrapscript :)

The bootstrapper was written in Elm, because its parsing combinator library is by far the nicest to use.

I wrote a rust bootstrapper in ~2019, but it was much too heavy for my experimentation phase. I think rust would be a good candidate going forward for the bootstrapper going forward though.

I'm open to suggestions!


Elm, a nice surprise.

I don't have experience with writing compilers, so I can't suggest anything. I just know that Haskell is promoted as a language suitable for this kind of task. Have you looked at it?


Yes, but I wasn't super happy with it. Rust was a much better option IMO.

I only chose Elm because I was experimenting with some visual debugging stuff, and boy, it's really a joyful experience. The problem with Elm is that it's impossible to write a serious compiler in it hahaha


Do you remember what made the Haskell experience unpleasant?


I can imagine enjoying Haskell in a team setting with existing patterns, but I think its flexibility gives my mind decision fatigue when starting from-scratch.


Do you mean the language in general or the tooling around compilers?


Neat!

Maybe check out the Joy programming language? It seems well-suited to this domain.


I'm definitely familiar with Joy. It's so elegant!

I tried to make a concatenate sister language to scrapscript called "sewerscript", but there's only so much time in the world.


Looks extremely fun. Coming from nix background, content addressability of stuff is a huge win. Looking forward to be able to play with this.


If you have any measure of success, you are 100% going to wind up with a thing in your ecosystem called "scrappy do"


This is awesome. I had a shell of an idea like this that never got anywhere. Wasn't even sure if it were feasible. Really neat!


I haven't fully understood this. Is this a way to share code? Where are the functions executed?


It's a way to share code in multiple ways:

- the language is like JSON, so you can send programs (and custom types) between computers

- you can store code in public "scrapyards", and send references to the scraps for others to download later and reuse

Code is executed on your machine, just like python, JS, etc.


Would you mind publishing a EBNF or similar grammar spec? That would make the syntax clearer.


I'll be aiming for basic documentation and specs next.

I first wanted to see if there was any community interest before dumping a ton of work into this project. I honestly didn't expect this much excitement :)


Would love to see more of the type system described.

If each scrap carries its own versions of its dependencies, then even the "same type" could actually be a "different type" because of version mismatches?


The version isn’t considered when comparing types. If the types structurally fits into the spot, you’re good to go.

I’m planning on publishing more of these kinds of details in the next month or two


I like the high level ideas and goals. I still have to get my head around the syntax and how it works in practice but will definitely keep an eye on this!


Surprised, none of the more functionally minded have jumped in. Looks interesting, I'll be taking a look, when it ships.


This looks like a fun thing!

It makes me feel like some hacker dweebs in the future would be communicating through this platform.


Did I miss the reference to the license?

Looks interesting though. Would like play with this when it's released.


Super cool!!


This is nuts and incredibly cool.


Looks fun!


Is this meant to be understood by geniuses or something? I'm halfway through reading about it and I still have absolutely no idea what any of this remotely means. Is the target audience for this genius hipsters who have 10,000 years of boilerplate context to even grok what the author is saying?


I agree. This whole page reads like nonsense to me. One easy example to point out:

    > # Optimized for AI & Autocomplete    
    > ```    
    > f a b    
    > . f = | x -> y -> x \* y    
    > . a = 1    
    > . b = 2    
    > ```    
    > Scrapscript encourages wishful thinking[0].    
    >     
    > Declare your goal up-front, and let your tooling make educated guesses about how to get there.
What does the title, example, and text have to do with each other? None of them seem to be talking about the same thing. What does AI have to do with this? How are these single character variable enable autocomplete? What does wishful thinking have to do with anything here?

I feel like I took crazy pills. Or maybe this is what having a stroke feels like.

[0]: https://wiki.c2.com/?WishfulThinking


Yeah, I'm hoping to put out a more readable guide soon! I didn't have the time/energy to put much of the necessary explanations and groundwork in there.

For this specific example, many languages have constructs like this:

  let x = 1 in f x
Scrapscript flips things around:

  f x . x = 1
I stole the phrase "wishful thinking" from the SICP lectures, where Sussman encourages writing the important parts first as if the details existed. I think this syntax encourages writing the big-picture ideas first.

For AI/autocomplete, tools like Github Copilot currently have to guess what you want from all the parts (e.g. variable names) you put on the table. By putting the variables last, the editor tooling can create boilerplate for your variables as you type.

Let me know if there's anything else that might need extra explanation!


Haskell uses keyword "where" for that. So the example corresponds to the following Haskell code:

    f a b where
      f = \x -> \y -> x * y           -- or f = (*)
      a = 1
      b = 2


  > . f = | x -> y -> x \* y
What do these symbols mean “|” “\*”


The `|` operator indicates that you're starting a function. And `*` is basic multiplication.

Scrapscript:

  | x -> y -> x * y
Javascript:

  x => y => x * y
It also works as a pattern-matching statement.

  | true  -> true  -> 2
  | true  -> false -> 1
  | false -> true  -> 1
  | false -> false -> 0


This comment here cleared up a lot of things and I'm beginning to understand what you are doing here. Let me be upfront about one thing, I do not think I am your target audience. But, I am happy to provide some feedback as I procrastinate on other things.

With regards to AI, I think focusing on the fancy auto-complete isn't really a great idea. This seems designed around AI as it is now, not where it will be. But, I see your point, especially where your approach solves other issues. I think the page would be better served if you mentioned AI/auto-complete more as a side-effect than intent.

---

A small nit before I dive into my main point: the page is a pain to copy and paste from. Things like title capitalization should not be lost when doing so.

---

My biggest issue with this page is that it says it solves several issues but handwaves critical details and doesn't demonstrate the value proposition of scrapscript when claiming to solve them. You make a very big claim at the beginning that you are solving all of these problems:

> APIs diverge, packages crumble, configs ossify, serialization corrupts, git tangles, dependencies break, documentation dies, vulnerabilities surface, etc.

but the page is very lacking in the details of what parts of those problems scrapscript are solving (many of these have multiple vectors), and in places where it does, it often leaves out critical details, uses very simplistic examples that feel trivially solvable in many languages, or provides only example code that is difficult for newcomers to relate to its section.

For instance, I assume the APIs diverge claim is addressed under the section `Typecheck Across Network Bounds`:

> The scrapscript compiler tells you when remote APIs differ from the code. And if the API changes while the code is running, scrapscript offers a series of graceful handling options.

What are these graceful handling options? (Separately, is the compiler reaching out to these scrapyards every time it runs?)

I'm also not convinced some of these problems are solved. For example, documentation dies. I am guessing this is addressed by the `Self-Documenting Typed Configs` section. From that, I'm guessing the documentation referenced is auto-generated. But, the most important part of documentation is intent, which is usually not captured by code. In your example:

    my-org:my-config
    { name = "my-server-001"
    , cpus = :4
    , mem  = :16
    }
    . my-org = : my-config
      { name = text
      , cpus = : 1 : 2 : 4 : 8
      , mem  = : 1 : 2 : 4 : 8 : 16 : 32
      }
Why am I setting these values in the config? Admittedly I know what they can be, but not why our how they are used. That, to me, is the documentation that is most important and I don't see how scrapscript solves that.

Overall, I think you should be very explicit about which presented issue each section of document is addressing. More details about how they are being solved need to be shared. And better examples should be used to demonstrate why scrapscript is the superior choice to solving these issues rather than other languages and their libraries.

All in all, there's a lot of cool stuff in here, and I bet this is just a result of you not having the time to spend on this page. But right now, this page comes across as a lot of empty marketing (and there are a lot of buzzwords).

I do have other, language-specific concerns (e.g. time != versioning, scrapscript assurances that all programs are safe to send around, `echo "'err red'"`), but I don't feel like there's enough information on this page for me to intelligently raise them.

Good luck!


This is incredible feedback! Thank you for taking the time to write it out.

My best friend gave me much of the same advice before I published the page, but I became too impatient.

I've bookmarked your comment, and will make sure to include deeper explanations in the near future

Thank you :)


I'm pretty sure that this is demonstrating that you can (have to?) write your definitions after the main expression, then suggesting that this encourages a development style in which you first write what you want the main output to be, then later write implementations for everything. It then further suggests that this style can work well with intelligent tooling, presumably by having autocomplete automatically infer definitions for the types you used or by having AI write implementations.


> Is this meant to be understood by geniuses or something?

Nope; anyone who has some basic programming knowledge and perhaps a high level understanding about how different programming languages work. And the ability to connect some dots together. I'm old enough to have learned BASIC programming on an Apple II and took Pascal in college, which is the extent of my formal programming training.

> “it’s JSON with types and functions and hashed references”

Another way to say this: it's executable YAML, which is a strict superset of JSON [1]. I like YAML, so that's what came to mind when looking at ScrapScript code. I also like clean, minimal syntax when I can get it, like YAML, CoffeeScript or Haml.

> “it’s a language with a weird IPFS thing”

I’ve been playing with IPFS [2] since its early days in 2015, though not much recently, though this will probably get me back into it. Content addressing solves a lot of problems that I won’t get into here but it’s certainly not that hard to grasp. IPFS is available for pretty much every browser these days and is integrated into the Brave browser [3].

> all programs are data

This concept has been around since the creation of Lisp in the 1950's. This enables all kinds of cool features the computer science types get excited about. I've known about this concept since the 80's when I used to teach kids Logo (which is a Lisp). The term used nowadays is homoiconicity [4] but that term wasn't in widespread use until fairly recently.

Bottom line: ScrapScript sounds very interesting and I'm looking forward to checking it out.

[1]: https://yaml.org/spec/1.2.2/#12-yaml-history

[2]: https://ipfs.tech

[3]: https://brave.com/brave-integrates-ipfs/

[4]: https://en.wikipedia.org/wiki/Homoiconicity


What a funny hoax.


What does this even mean?


You don't know what funny is our you don't know what a hoax is?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: