When you design a programming language it's import...
# thinking-together
v
When you design a programming language it's important to ensure that it is convenient. Seems like the best way to do it is to write a program in this imaginary language. What are good problems to try out with this imaginary language? * a backend for blog web app, * a backend for webchat with websockets any other suggestions?
m
depends a lot on the target audience of the language. From examples you've listed, it looks like your audience is backend developers, but not necessarily focused on distributed programming. But this might not be the audience you initially target, so you'd probably need to pick examples that the audience would relate to the most
👍 4
j
Depends also on what the motivation for the language is, and it sounds like you are implicitly describing the case of server languages? If I am to create a language it is either because it should be a DSL that neatly describes a specific existing problem space, therefore examples would follow from that, OR it is because I am interested in trying to do “new categories of things” that I am unlikely to be able to describe accurately before the language has been prototyped. I think this is why Bret Victor got excited about Laser Socks.
👍 3
v
I want it to be ran on server, yes. But I don't limit it to it. I have a list of principles that I want to be followed during design of this language. I have list of features that I believe would support those principles. Now I want to imagine that this language already exist and write a program.
j
So you have principles and features, but what is the overall motivation?
v
Make programming more efficient in terms of human-computer interaction.
Use abstractions that easy to work with. Abstractions that play along with visual interface. Abstractions that play along with collaboration.
d
Can you share your list of principles and features @Vladimir Gordeev ?
j
Efficient in what way? What does “easy to work with” mean, and who does it apply to? I’m not demanding answers, just suggesting questions that might help you towards more example programs 🙂
v
@jarm efficient in sense that people spend less time solving it. Faster to grasp what unknown program does. Faster to locate what part of the system causes the problem. Faster to iterate in development cycle: run, change. I see problems in abstractions that we use. They allow too much flexibility, have too many dependencies.
@Daniel Garcia I need to write down a summary
@Daniel Garcia something like that: * Collaboration is the key to efficiency. Everything should be easy to share, to detach, to attach, to reproduce. Anything is possible to comment, tag, bookmark, reference. * structure based source code stored in something like database. Code edited through browser, there are no text files on disk * basic data abstraction is DAG. Fits well with file systems, with source code presentation. Lists, tuples and dicts are perfectly expressed by DAG. * peers are working in same workspace connected to each other. All code changes are always stored. There is no such thing as uncommited code. Everything is searchable. * there are functions and actors. Communication between actors happens through channels. * program is just a graph of actors that connected through channels. * visualization of the data is just another actor that stored in shared workspace. * Complicated system/service consists of several layers of programs. Layer above can manipulate parts of level below, but cannon break inside parts. This reminds a lot composition of DSLs, but not really. Haven't figured out exactly how it should work yet.
✨ 1
👍 3
j
Sounds cool!
Faster to grasp what unknown program does.
Faster to locate what part of the system causes the problem.
Faster to iterate in development cycle: run, change.
It seems from this that the example program is less relevant than the scenario that would allow you demonstrate these activities. E.g. “someone else’s program”, “a program with a problem”, “several versions of the same program”. So it could be just one example program, demonstrating these activities. If this was a demo, then your audience would start to forget about the specific example and think more about the properties of the language? Just a thought!
v
That's reasonable. You see, part that is responsible for collaboration is a workspace part, a runtime + UI. I will get there eventually. For now I just want to check that I picked up set of abstractions correctly. Ensure that functions + actors + DAG data is enough and convenient.
s
As a game developer I like to see small non-trivial games, like a simple shmup (space invaders) or platformer (mario) or if its 3D maybe an FPS (doom). None of those really apply to something focused on backend however.
👍 2
A photo sharing app might be a good example, especially if it does some simple batch processing on photos (resize of blur or something)
v
Thanks, these are good ideas.
e
i have been working on a set of reference programs that go from trivial upwards gradually. Starting with 100 word programs up to 1500 words. A nice progression of graphical interactive programs 1) a analog clock, 2) a wristwatch simulation, 3) snake, 4) tic-tac-toe, 5) minesweeper, 6) chess (with no AI, just allows you to play), 7) networked tictactoe where you can see a dozen games playing at once and can join one or more. For client side, this covers a lot of basic ground. You can also go more into business, where you start building reports that print multi-page summaries with subtotals and sorting (like a stock portfolio report). You can go into text processing, there are of course limitless areas. I have some of the ingredients and specs on my blog, and it is great that the Red team has implemented some of these as well. The key thing is to have a progression that gradually adds more things to the mix. Handling bitmaps, sound effects, user interface tracking, and most importantly resizing of the screen gracefully. We live in a world now of multiple devices. The days where you could just pick a popular resolution and go with it over; there are devices 400+ dpi and ones that are around 90, no fixed layout will work, so you must grapple with how are you going to allow people to lay out stuff without hard-coding coordinates. This is something that is a bit of an achilles heel in many languages, where the burden is put entirely on the user to handle this.
👍 1
You can build on paper many of these applications, and bench simulate them to test out your language. A great way to iterate without having to build a compiler first. I also recommend building the runtime before you build the compiler as it is oh so easy to create a language that is difficult, if not impossible to compile. You can invent a function called "draw beautiful diagram", but how exactly does that work? That is where the runtime crystalizes your thinking.
👍 2
v
Thank you for your advice.
Games are indeed are good little programs to try out
d
Hmm, my approach is to focus on things I notice are painful in all popular languages, and design features that would make those things less painful. Then maybe I'd make the most diverse and complicated app I can think of that fits in 1000 lines of code and takes full advantage of the features I just designed.
e
well, i built a progression of apps, from a clock (150 words) to Chess (1500 words). I think that Chess (no AI, just switching sides) is hard enough to show your language's worth. Lines of code is a bad metric, i want people to start using words like they do in the newspaper business. Some languages are more horizontal vs. vertical, and so lines of code is highly misleading, but words isn't, and in most text editors you can get a word count and that gives you a much better feel for the "weight" of a program. It also avoid penalizing people who write a more visually sparse style. Who cares about how much blank space is used in the language, it is the number of tokens you have to enter and process mentally that is the effort.
And by the way in small programs like this you can achieve near perfection, and the smaller the program the more similar they are, but once you get to 1500 words the languages diverge rather greatly, and then it becomes a very interesting comparison. Of course i am focusing on graphical interactive application space, and simple games are excellent testing grounds.
s
@Edward de Jong / Beads Project Are you just using Unix’
wc
to count words in code? I find lines of code practical and acceptable, if comments and empty lines are stripped (like
cloc
does), and coding style with one statement per line can be assumed. But I’m super interested in other (simple) ways to measure code complexity, so counting words sounds intriguing. And is the source for your progression of apps available online (GitHub maybe) to take a look?
e
i am using the macintosh program called "TextWrangler", which is very similar to NotePad++. not sure if it counts word exactly the same as wc. I haven't posted all of the apps yet, but i did post the first two (clock and wristwatch). Yes of course you have to strip comments out before counting the words. You can't use lines because then you get a huge advantage for horizontal languages like Red which would unfairly lead you to the conclusion that Red programs are 1/5th that of other languages, which in reality they are merely very horizontal with lots of run on/ chaining operators which is reminiscent of APL.
i am not familiar with cloc, that isn't a command line tool in my OSX/Unix command line, must be a tool from some other OS.
w
wc
works for me! As a rough measure. One problem is that line counts inevitably go up with refactoring. But what I'd really like is a measure of whether an abstraction is actually carrying its weight vs creating useless indirection.
s
Cool, thanks for explaining your process, @Edward de Jong / Beads Project!
cloc
is just a simple script you can easily install through homebrew. I guess both LOC and word approaches are far from an exact science. I can see why counting words is more useful when you deal with smaller snippets of code. I don’t know Red, and I suppose that both language features and coding style are a consideration for the word-based approach too, as for instance
for (int i = 0; i <= 100; i++) {
and
for(int i=0;i<=100;i++){
are 10 vs. 2 words, if just using spaces as delimiter (what
wc
does by default). Both are a good examples for applying a lower-level concept that considers the data to just be text for a domain where the data actually has higher-level structure. What we get is a much simpler (and more commonly available) tool, which also turns out to be rather imprecise for the domain were applying it to. Still good enough for many use cases, especially if language and style can be assumed stable across comparisons.
w
I honestly think
wc
only works when coding style is fixed. And it certainly has been predictive of our larger rewrites. Those that include a 2x+ reduction tend to be kept and those that end up with a 2x+ increase tend to get abandoned for the old system.
e
A more precise count of the for (int... expression is that it has 15 tokens: [for], [(], [int] [i],... etc and ++ is a single token. To count accurately you must tokenize the input file, stripping away the spaces and comments. Then you have a nice even apples-to-apples comparison. It also eliminates the differences between variable name lengths which varies between programmers, and should be ignored when trying to compare overall input effort. Then you take two programs written in different languages, count the words, and then you see if there is any great productivity difference.
There are vertical and horizonal languages, and by using word count you can truly compare them. Why the emphasis on word counts? because it has been known for decades that people program at about the same rate in terms of human output regardless of the language, and a more powerful language that is more compact is thus more productive.
In building the simple progression of apps that i have had the various members of the next gen developers do, you can more easily compare the languages. You put the programs side by side and you can see the advantages/disadvantages of the various syntaxes. Notation matters, and as the test programs grow in complexity you really start to see a divergence in the quality of the code. By the time you get to a chess program which is about 1500 words, some toolchains/languages start to get cumbersome. if you include in the specification a requirement that the user interface adapt to the resolution of the device it is on, then things really get ugly, and many people then fall back to very complex graphical framework add-ons, which are more complex to learn than the language itself. This what i call the "graphical pitfall", where you go into a black pit of complexity trying to handle drawing gracefully. Forget the days of hard-coded XY coordinates in your programs, that is long gone, unless you treat the whole screen as a rubber rectangle that is squished. But that doesn't work in the end, because if you have a big screen you might change how many columns you use. Since many programs need to be graphical nowadays, unless you are limiting yourself to server-side only, you better tackle the layout problem in the language or else you are just ducking one of the main requirements.
The Dark language for example, is agnostic as to what database you hook up to. It is not trying to include the database features into the language. But some of the other efforts include a database in the language. Some languages will include a drawing system, some use a library like Red which has a domain specific language for rendering. Others just dump you into CSS/HTML/JS type of drawing. I think this is the most important design decision in the language itself: will it have a database inside? will it include drawing? If the answer is no to both, how will you actually get past current state of the art? Can you honestly expect to bury Java and Python and C++ without those two things? I think that is a very interesting question.