Hacker News new | ask | show | jobs
by jmholla 1147 days ago
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

2 comments

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.