Hacker News new | past | comments | ask | show | jobs | submit login
Bosque Programming Language (microsoft.com)
123 points by matt_d on April 17, 2019 | hide | past | favorite | 146 comments

Hi project owner (Mark) here. It is a bit late in the evening for me but I will try to answer any questions when I can.

The Bosque language is currently in a very early state with lots of work to do and not ready for practical use. However, I am very excited by the potential in the concepts and wanted to make the project a collaborative endeavor, including both other academics and developer community, from the start. At this point the goal is to explore interesting options in the language design space – whether the Bosque language becomes mainstream or just provides useful ideas for other languages to adopt. So, please take a look, expect plenty of rough edges, and we would love comments, suggestions, and PR’s on the GitHub repo.

Hello! Disclaimer: I haven’t read the full publication yet and I’ve only skimmed it.

A lot of programming languages that are coming out these days talk about simplicity, lowering “cognitive load”, increasing expressiveness, being nimble/lightweight/easy/whatever, and—this one stated by you—reducing “accidental complexity”. When I looked at your grammar and some examples, I saw atomic building blocks that don’t lead to any less complexity than what I’d get if I strung together similar building blocks in Lisp or Python or ML.

To me, “accidental complexity” doesn’t seem like a very well defined concept. I might say such a term in a meeting room arguing to upper management that we need to pay off tech debt. Or I might blog using such a term to talk vaguely philosophically about software engineering. But I don’t think I’d find myself using it in a formal context to argue the merits (or lack thereof) of a technology. I admit that this may be due to my ignorance of a term of art.

The introduction to your publication is even more bold: “Regularized programming” (and hence Bosque) will (supposedly) unleash a revolution on programming the same way structured programming did the paradigms before it, ushering a “golden age” of programming and the like.

Focusing on the term “accidental complexity”, can you elaborate what that means? What is an example of accidental complexity and how does it naturally come about with the current crop of languages. And how—in the large—does this programming language avoid it (or help the programmer avoid it)?

Edit: I see in your publication, upon the mention of “accidental”, you cite “Frederick P. Brooks, Jr. 1987. No Silver Bullet Essence and Accidents of Software Engineering. Computer 20 (1987), 10–19.” But in reading this [0], Brooks says:

> The complexity of software is an essential property, not an accidental one.

He only speaks of certain difficulties as being “accidental”, and past ways in which we’ve improved the impedance of such difficulties.

[0] http://www.cs.nott.ac.uk/~pszcah/G51ISS/Documents/NoSilverBu...

I would say accidental complexity comes from mostly historical reasons. Two sources discussed in the report are reference equality and looping. These make a ton of sense if you are implementing a language with a compiler that targets an x86 processor. They map naturally to the features of the hardware but make other tasks impractical, e.g. compilation to a FPGA or verifying a SemVer dependency update doesn’t break your application.

Section 5 of the paper explores some scenarios that, once this “accidental complexity” has been removed, become much more feasible. These types of experiences are currently aspirational, and much work remains, but the hope is to demonstrate the practicality and value of these concepts.

This is the exact goal of the removal of “incidental algorithms”, as described in a number of papers/talks by Sean Parent, Mat Marcus, Jaakko Järvi, et al. They mostly explore this in the setting of GUI behavior implementation.

I wish PL researchers would actually run studies to measure cognitive load and usability metrics while using their language compared to some other language.

I would do it if the right PhD student came along!

I have never investigated this, but I feel that PL pragamtics and PL-feel is relatively under researched.

I talked about this with colleagues a few years back, but we had very distinctly different feelings about what we were doing when writing C vs C#: C often feels more like writing text that will be translated to code while C# already feels like you are manipulating code. It makes no sense when I write this out but that's phemenology for ya.

This is interesting. I "feel" this in Visual Studio, as the DE is more tightly I(ntegrated). Do you still feel like this in the context of a plugin-less plain editor?

Running any study with real humans is very expensive. We can measure simple things empirically (eg reaction time), but trying to measure something such has “cognitive load” is probably impossible, and what is a usability metric? Do those already exist for PL or so they need to be invented somehow?

We (PL researchers) think about this a lot, but so far no one has come up with any good answers on how to empirically measure PL usability for an entire PL (vs chipping off small features to evaluate). At best, we can run qualitative studies with little in the way of rigor.

> I would do it if the right PhD student came along!

Quit trying to lure unsuspecting CS grads into your van!

>To me, “accidental complexity” doesn’t seem like a very well defined concept. I might say such a term in a meeting room arguing to upper management that we need to pay off tech debt. Or I might blog using such a term to talk vaguely philosophically about software engineering. But I don’t think I’d find myself using it in a formal context to argue the merits (or lack thereof) of a technology.

That sounds bizarro. Accidental complexity is pretty obvious to show in an example of a function or an application architecture or class.

It might be harder to define in abstract (except as e.g. "complexity not imposed inevitably by the functionality/problem domain"), but it's very easily observable in specific code examples.

Can you show me some examples? I understand complexity, I also understand incidental complexity, but I’m not sure about it being accidental.

Google the "Out of the Tar Pit" paper by Moseley and Marks. After incidental complexity, Accidental complexity is the all remaining stuff. It's the complexity you wouldn't have to deal with in an ideal perfect world. For example: manual memory management, performance optimisations, JavaScript equality semantics, aspect-oriented programming, dependency injection frameworks or any other ad-hoc technology to work around issues further down in the stack.

I hope you do not mind, if I make some comments. The first is that you should try to include realistic examples in your documentation and promote good coding styles. For example, I do not see the benefit of a 'sign' function with an optional argument. Or have a 'sign' function that uses a local variable, while this could also be done with an if-statement or the ?-operator.

I do not understand the concept op typed strings. Would that not be simple a subtype of strings (implementing additional restrictions on the values of the strings, a true substype)?

Also, when I see something like: 'args.all(fn(x) => x % 2 == 1)' I do experience it as 'simple, obvious, and easy to reason about for both humans and machines' because it only makes sense if you already have a lot of knowledge about languages like TypeScript. I think that something like: 'All x in args: x % 2 == 1' is easier to read. BTW, why does 'fn(x)' not have a type? Are types optional in your langauge?

I would not give examples of mechanisms that have not been implemented and seem to go against your principle ideas, such as references. What happens, I pass a part of a value to a 'ref' argument of a function?

There are some other language out there that are only based on immutable values. If you are fond of immutable values, why not implement them in an existing language and see how far you get. This has the benefit that people do not have to learn a new language and keeps you from reimplementing a lot of stuff that others already have implemented.

>I do not see the benefit of a 'sign' function with an optional argument

Perhaps you don't see the benefit of an identity function either ("why not just use the variable")?

Encapsulating things in a function instead of a statement is key to certain patterns (and functional style).

I agree with GP. The 'sign' function with a mandatory argument I understand. Making the argument optional I don't understand.

I think its less about a sign function than about showing how optional (i.e. nullable) values work. Most languages have them, and making that possibility explicit is recent best practice.

As fjfaase said “The first is that you should try to include realistic examples in your documentation and promote good coding styles.”

That ‘sign’ example could be somewhat improved by having it return an optional int instead (returning null on null inputs), or by having it take a double and return an optional int (returning null for not-a-numbers), but I think it isn’t that hard to come up with a more realistic short example.

I think the typed string is to sort of the same as typed lists. The string can be thought of as a container for the type it holds.

Thanks for your work, this looks exciting!

I am curious about the following:

> Since the semantics and design of the language ensure fully determinized execution of any code there is actually no real need to perform logging within a block of code. So, logging is not available in the compute language.

While this may be true for execution, this is not true of data on which the program operates. For example, when processing large amounts of data, how should one keep track of statistics, performance information, data irregularities (which don't cause errors but may be useful to look into further), and other such events which might otherwise be logged?

Similarly, suppose the program performs some operation which depends on the system time which fails at runtime for certain system times. If run in deployed mode, it would restart and run the same thing in debug mode, but the environment would be different. How would such an operation be able to be traced back to the particular conditions which caused the error?

Great question. We take a very maximalist stance here and do not provide any environmental API’s in the Bosque language. Instead all IO, data-time, IP address operations must be part of a host platform – similar to how JavaScript does not provide IO or an event loop in the spec but relies on the browser or Node.js to provide it.

With this model the host can just log/record the environment interactions. The details of this host and integration are an open issue, both research and engineering, but I am very excited by the AMBROSIA architecture (https://github.com/Microsoft/AMBROSIA) by one of my colleagues as a possible design.

I was keen to read about this lang bc it came from m$, but this looks like it needs some work: I'd highly suggest changing "var" and "var!" definitions.

From your doc:

>var z = 5;

z = y; //error z is not updatable

"var" is shorthand for 'variable' as you're no doubt aware, so use "const", or use something else altogether to indicate a var.

I stopped reading after coming across your unintuitive "var!" syntax. Let an apple be an apple and an orange an orange.

You seem to have some goals in common with Floyd. Maybe you want to get in touch.

https://github.com/marcusz/floyd https://www.reddit.com/r/ProgrammingLanguages/comments/arwjl...

Hi Mark! What's this language's purpose and how will it be better at that than existing languages?

The current purpose is explore language design choices and their impact on their general utility for programmers and enabling automated developer tools (like verifiers and compilers). The hope is to use Bosque as a proof of concept for various ideas.

Some examples of better than existing languages are included as case studies in section 5 of the technical report:

-Automatically finding (ideally) any runtime error and producing a test case for it.

-Verifying that a SemVer update is safe or flagging where it will change the behavior of your code.

-Supporting compilation to high speed SIMD code or other accelerator architectures.

This is all still an aspirational goal and a lot of work remains though.

> -Verifying that a SemVer update is safe or flagging where it will change the behavior of your code.

Isn't that similar to what Elm does?

My understanding it Elm checks for signature changes such as adding a parameter to a function. We would like to do more and actually compare the actual behavior of the code before/after the change as well.

Sounds like it, but Elm is only for front-end web dev.

Could you comment on how you came up with the name, or its meaning?

It is a Spanish word used in the SouthWest US for forest along a river. No particular reason behind the name, just a unique and easily searchable choice.

Oh okay. I thought it might have something to do with Basque:

"Basque is a language spoken in the Basque Country, a region that straddles the westernmost Pyrenees in adjacent parts of northern Spain and southwestern France. Linguistically, Basque is unrelated to the other languages of Europe and is a language isolate to any other known living language."

I didn't know about the forest meaning at all. (Maybe a subconscious influence, if you've ever heard any reference to Basque.)

I'll spell it out (for the downvoter): "is a language isolate to any other known living language" as well as being "a language". It has a very special status between France and Spain. I think anyone who knows about Basque would think of Basque when reading about a computer language named Bosque.

Not really: Bosque, Bosco, Bois, Bos, all mean "wood", "forest" in, respectively, Spanish and Portuguese, Italian, French, Dutch. So it's a pretty familiar word to most Europeans.

OK, thanks.

Not if you speak Spanish. "Un bosque," a forest, isn't related to Euskera, as the Basque language in known in Spanish. That part of Spain is called Euskadi or País Vasco, neither of which looks like bosque in Spanish nor Basque in English.

Bosque is spanish for "forest" (not necesarily along a river).


Sounds offensive to me.

First of all, the community here discusses the post, and whatever they like about the language and announcement -- and whatever they think of tied (loosely or not, to that).

We're not here as some committee with some explicit purpose to give relevant PL criticism.

I don't mind you being offended, I was talking to the creator.

They're bikeshedding there as well. Just filter out any post that contains the word syntax.

Technical discussion is usually still leagues better on reddit than here

There's an English error on the very first sentence of the description on the Microsoft site.

> There's an English error on the very first sentence of the description on the Microsoft site. [emphasis added]

The correct usage would be to talk about an error "in" a sentence, not "on" a sentence.

Muphry's law get you every time!


Surely you didn't mean too but the correct tense of "get" on you're sentence would be "gets"

> on you're sentence would be "gets"

this just gets better and better

That was to make sure I didnt violate Muphry's law!

More accurately, Skitt's Law (which is mentioned in that Wikipedia article).

> Muphry

Sems like it got you too!

(Yes that was intentional

In this case the misspelling is actually the correct one. HN has shortened the link in GPs post but if you follow it you'll see it spelled "Muphry's law", and it is a separate one from the general one that everyone knows about.

That said it wouldn't surprise me at all if I've misspelled something here : )

The error is a missing word if anyone is wondering.

"The Bosque programming language is designed for writing code that _is_ simple, obvious, and easy to reason about for both humans and machines."

So what?

Some comments on the code, based on Tictactoe example (https://github.com/Microsoft/BosqueLanguage/blob/master/docs...):

1. overall quite nice looking and easy to understand

2. too verbose in places, e.g. this constant structure:

    const winPositionOptions: List[List[[Int, Int]]] = List[List[[Int, Int]]]@{
        List[[Int, Int]]@{ @[ 0, 0 ], @[ 0, 1 ], @[ 0, 2 ] },
        List[[Int, Int]]@{ @[ 0, 1 ], @[ 1, 1 ], @[ 2, 1 ] },
        List[[Int, Int]]@{ @[ 0, 2 ], @[ 1, 2 ], @[ 2, 2 ] },

        List[[Int, Int]]@{ @[ 0, 0 ], @[ 1, 0 ], @[ 2, 0 ] },
        List[[Int, Int]]@{ @[ 1, 0 ], @[ 1, 1 ], @[ 1, 2 ] },
        List[[Int, Int]]@{ @[ 2, 0 ], @[ 2, 1 ], @[ 2, 2 ] },

        List[[Int, Int]]@{ @[ 0, 0 ], @[ 1, 1 ], @[ 2, 2 ] },
        List[[Int, Int]]@{ @[ 0, 2 ], @[ 1, 1 ], @[ 2, 0 ] }
Has types defined in 10 places, 9 of which are redundant.

Also you are using @{...} for lists and @[...] for tuples; a more usual convention (in e.g. Python or Haskell) would be [...] and (...) respectively.

3. String types aren't intuitive (at least to me). E.g. in this code:

    const playerX: String[PlayerMark] = 'x'#PlayerMark;
It appears that a String[PlayerMark] is a subset of String that can have the values 'x' or 'o'.

I would have preferred something like:

    type PlayerMark = 'x' | 'o';
    type PlayerMarkOrBlank = 'x' | 'o' | ' ';

Got to say, after reading the description in the linked URL, I was really surprised with just how complex the syntax is in the code samples. I don't want to be overly negative, but it doesn't look like it's going to reduce complexity to me - if anything it looks like one of the most incomprehensible languages I've come across in decades of experience.

I agree! Human-readability may have been a goal, but it wasn't a top priority.

A random thought about the code samples. What do we gain from having to write

instead of other languages'

    point.y = value

I believe that syntax should be designed to make things simple for developers, not for the designers of languages or for compilers.

I don't know anything about the language but the first form suggests immutability (return a new point with the y property = to value), the second looks like mutating a struct

I don't see anything intrinsically different about the two. If anything the established notation of mathematics for hundreds of years is that '=' implies immutability.

The second example suggests to me that `point` already exists, and we're mutating it by changing the value of its `y` property.

<~ looks like an expression for a bulk update of an immutable record.

"point.y = value" is typically a statement for a single update of a mutable record.

I'm not sure how you'd extend the latter to support the features of the former. The meaning is completely different. Different things should look different.

I expand a little my point. This is from Elixir, functional and immutable, which I've been working with for a couple of years

    iex(1)> point = %{x: 1, y: 2, z: 3}
    %{x: 1, y: 2, z: 3}
Of course this doesn't work

    iex(2)> point.x = 4
    ** (CompileError) iex:2: cannot invoke remote function point.x/0 inside match
This is how we do it, verbosely

    iex(3)> Map.put(point, :x, 4)
    %{x: 4, y: 2, z: 3}
Or with a syntax shortcut

    iex(4)> %{point | x: 4}
    %{x: 4, y: 2, z: 3}
A better syntax shortcut would be the usual

    iex(nope)> point.x = 4
    %{x: 4, y: 2, z: 3}
which everybody would understand no matter the language of origin. I imagine that it would require quite an overhaul of the internals of the compiler, but the compiler should bend to us, not us to the compiler. This is my point about obscure language syntaxes.

The problem with the last code snippet is that it looks like mutating the original value, and that would mislead newcomers to the language.

Yes, that's possible. However this is an example from Ruby, which is very mutable but has some immutable features in its standard library.

    2.3.0 :001 > s = "abc"
    => "abc" 
    2.3.0 :002 > s.gsub("b", "B")
    => "aBc" 
    2.3.0 :003 > s
    => "abc" 
    2.3.0 :004 > s.gsub!("b", "B")
    => "aBc" 
    2.3.0 :005 > s
    => "aBc" 
I guess that if an immutable language shows some mutable syntax we can expect it to be a short form. Actually Elixir has at least a mutable short form:

    iex(1)> s = "abc"
    iex(2)> String.replace(s, "b", "B")
    iex(3)> s
The next line would be an error in Erlang and other languages because we can't mutate an already assigned variable there, but Elixir allows rebinding

    iex(4)> s = String.replace(s, "b", "B")
    iex(5)> s

I would not understand that. In every language I've used that supported "point.x = 4", the returned value (if there is one) is 4, not point. Bosque's update is more like CONS (or conj) than . =

Your proposed syntax also doesn't have any obvious way to do a bulk update, and I'm not sure what syntax you're proposing for that.

I maintain that it's more important for things to look like how they act, rather than look familiar -- especially if the familiar appearance does something functionally different -- https://stackoverflow.com/a/522168

I think this is nicely solved in Swift.

How? I don't know any way to do a bulk update of an immutable structure in Swift, apart from constructing an entirely new structure and passing all values (not just changed ones) to its initializer.

You can just declare all members of the structure as vars. The structure will still be immutable.

Or to use Scala's syntax which is more clear to me:


I really like F#'s approach to this

    let point2 = { point1 with y = value }

EDIT This is inherited from OCaml - https://v1.realworldocaml.org/v1/en/html/records.html#functi...

"Choosing the equal sign to denote assignment is one notoriously bad example that goes back to Fortran in 1957 and has been copied blindly by armies of language designers since. This bad idea overthrows a century-old tradition to let = denote a comparison for equality, a predicate that is either true or false. But Fortran made this symbol mean assignment, the enforcing of equality. In this case, the operands are on unequal footing: The left operand, a variable, is to be made equal to the right operand, an expression. Thus, x = y does not mean the same thing as y = x. Algol corrected this mistake with a simple solution: Let assignment be denoted by :=."

--Niklaus Wirth (Good Ideas,Through the Looking Glass)

Equals is a verb AND a adjective though. So I disagree it's notoriously bad to use it as assignment. This is a situation solved entirely with = (make these equals) and == (are these equals?).

>Thus, x = y does not mean the same thing as y = x.

Unless it does, or should.

The specfic argument you're arguing here is on that is just a simple syntax. You don't like = for assignment, but I do. You like = for comparison, but I like ==... To be fair === is dumb.

You're arguing that point<~(y=value) makes sense, and I'm still not seeing it.

But why change the meaning of one of the most common mathematical symbols? Every new generation of programmers must then relearn what "=" means. If you see "=" in a comment you are never really sure what it means, is it assignment or is it the standard mathematical predicate?

Most programming languages change the meaning of one of the most common mathematical symbols. There are at least 3 meanings of "X = Y".

Pascal: Is X equal to Y?

C: Change X, making it equal to Y.

Mathematics: X is equal to Y.

Those are all valuable in programming. Normally programmers get the mathematical meaning via a feature such as __assume or __builtin_expect or assert. It can be used for optimization. When the constraint is violated, various bad things can happen. The code can run slower, halt with an error message, or behave in an undefined way.

Every new generation of programmers starts off expecting the mathematical meaning. I don't know of any programming language which uses it. Ideally that would be fixed, but the change might be difficult for the current generation of programmers.

Note that the Pascal meaning can be fairly compatible with the other meanings. The solution is simply to be aware of context. On a line by itself, X=Y makes no sense as an equality test. Within the controlling part of an "if" or loop, assignment need not be supported. That does the job. Alternately, the meaning could change by having a keyword in front for assignment ("let" is popular) and/or for the assertion. So we could distinguish all three meanings with syntax like "if X=Y", "let X=Y", and "assume X=Y".

It's not changing the meaning at all. You're picking your preferred meaning, and I'm picking mine. Mine happens to be the almost universal standard for programming.

Most lines of code are written as true statements. If you understand how a computer actually works at the register level you'd see that

x=5; has a result. And it's not 5. It's TRUE. I'm not asking if x equals 5, I'm saying HEY YOU, X IS EQUAL TO 5. I'm telling the computer this is now the truth. 5 is moved into the x RAM location and the result is true, because the CPU is doing what I told it.

You're just wrapped up in your semantic view. There is nothing wrong with = for assignment and == for evaluation. Someone would complain if it was the other way around, so just accept this is the standard - or make your own language that "does things right". But.... Just because it isn't the way you like it, doesn't make it wrong.

Lisp, the second oldest language after Fortran, didn't make this mistake. In Lisp, "=" isn't an operator at all. Assignment is (setf x y) and comparison is (eq x y) [and several variants of eq].

Common Lisp and related languages have = as a function: it is a numeric comparison. Like under equalp, (= 1 1.0) yields true. You might think it's superfluous to equalp, but has some virtues of its own, like supporting variadic arguments (= 1 1 1 1) and rejecting non-numeric arguments.

eq is often the wrong one to use: two instances of the same number can fail to be eq.

This is a bulk record update, according to what I can find in the docs. It's an atomic operation -- meaning, if instead of updating one field, you updated thirty fields, all would appear to take place as one operation.

Obviously someone please correct me if I'm wrong.

Am I the only one who really can't stand the expression "easy to reason about"? Everywhere you look everything that isn't exactly CORBA, ASN1., EJBs or XMLs is E2RA...

I thought "easy to reason about" was reserved for pure functional programming languages :-)

And modern EJBs are actually not to bad either : )

> Thus, Bosque does not have any undefined behavior

I think this is the one that should be highlighted most. Otherwise, from an engineering perspective, many of the other language features have already been implemented and widely used in other languages

I think I remember someone talk about undefined behavior in specifications and how it is actually a good thing, in the sense that offers increased liberty for implementations and some other advantages. Anybody else has heard this? Don't quite remember where I read it.

My humble opinion aligns with yours, it seems intuitively "better" to have no undefined behavior.


Yes, I've heard the same thing. The C and C++ specifications specifically mention that some things are undefined behaivour, that shows that its not something that slipped through the cracks (at least in those cases) but rather a conscious decision to leave it undefined. This only makes sense if its done to allow the compiler room to do things like aggressive optimisation.

I only wish that undefined behaviour in C++ were harder to accidentally use, or at least, if the compiler warned me "hey, I'm gonna do X here because that undefined behaviour here allows me to do so, this may not be portable to other compilers and may not be what you wanted, you've been warned!"

The reason that these behaviors are undefined typically is that the compiler cannot prove whether or not a program will execute undefined behavior, and needing to account for it would lead to less efficient code. For example if (x+1 > x) can be simplified to if (true) for signed integers only because signed overflow is undefined.

That said, there is UBSan, which is a runtime checker for undefined behavior that can help you to identify if your code is depending on some undefined result.

Especially in C-like languages, undefined behavior is one of the main things that creates space for compilers to get better (produce faster code, or produce code faster, or smaller, etc). That topic comes up in compiler discussions every so often; I would hazard a guess that one of those references is what you have in mind.

Undefined behavior allows a compiler to make assumptions that some things never happen, which can allow them to generate more efficient code by not having to generate code that checks if those assumptions are correct.

If you're going around thinking computing resources are cheap, it doesn't make much sense to avoid those correctness checks, and undefined behavior is probably not good from that perspective.

I will always take an opportunity to link to Undefined Intimacy with the Machine[0].

Whether or not you agree with Evan Buswell, it is a solid argument, both for its thesis, and for the utility of Code Studies in general.

0: http://thoughtmesh.net/publish/367.php

That was the original rationale for introducing (formally) undefined behavior in the original C standard. Malicious optimization is a after-the-fact perversion of it.

Typed strings look really nice, something I tend to wish every language had eventually - though I'm not sure why you'd limit them to Strings and not allow them for all types? I really like the Logarithm example shown in the Dotty docs for instance: https://dotty.epfl.ch/docs/reference/other-new-features/opaq...

There were some discussions for a more general system -- e.g. Int[Seconds] would be a typed int indicating the contents represented seconds.

We needed to think more about all of these usecases and how things worked so we decided to start with just strings as the most useful. It is great to see you had the same idea though and would definitely like to revisit this in the future.

To be fair Strings would solve a problem I have right now with Scala pre-Dotty, our object IDs are all strings and the compiler does nothing to stop you using a user ID in a method that expects a contact ID, etc.

For your Int[Seconds] example, I haven't used them at all but could it work something like the F# measures concept? That seems sort-of similar but more general from scanning the docs.

Direct link to github repository:


The description suggests the syntax and type system are based on TypeScript. After looking through the docs I have to say I wish this were much more true. It seems like Microsoft Research has thrown out half the good ideas TypeScript has in favor of overly noisy, complex syntax.

Please consider using a license other than MIT. MIT assumes all contributors work for a single institution, and doesn't protect licensees from later patent infringement claims.


Either Apache 2.0 or Blue Oak Model would be better choices.

>MIT assumes all contributors work for a single institution

Could you expand on this? I can't see this assumption anywhere in the MIT license, and the link you provide doesn't clarify on this point.

I also find the Blue Oak license much more difficult to understand than the MIT license, FWIW.

I have never heard that either but I guess that impression might come from the first line of the MIT license:

> Copyright (c) <year> <copyright holders>

Where <copyright holders> is often filled as the company of the primary developer, e.g. "Facebook". What I often see (and use) to avoid this, is filling it in with "The <project> developers", e.g. "The React developers".

In the blog post linked above, I make the point that

> Copyright the Project developers

conveys zero information. Of course contributors to a software project hold copyright in it. Who else should?

But who are those contributors? The Blue Oak Model embraces the practical reality: When we want to know contributed to an open software project, we look to development files and revision-control data, not the license.

Ah I see, good point. I think management of code copyright is inherently complicated and not something that a license template can really fix. You do need to keep track of who has copyright of the code.

The link I provided does explain this, under the section “MIT and BSD don’t expect more contributors”, which reads in part:

“MIT and BSD terms include a space for a single copyright notice, because they were written for releases from academic institutions that own all the copyrights in their employees’ work. What about other contributors to the project? They hold copyright in their contributions.”

Apache 2.0 DOES address this issue in a complicated way, through the supplementary use of Contributor License Agreements. Other non-Apache projects like Fossil also require you to physically sign a CLA before contributing code to the project.

Blue Oak handles this in a more straightforward way, by explicitly saying that, as a condition of the license, every contributor in turn allows any use of their code that would otherwise infringe their copyright or patent claims. Who is a contributor? Anyone who contributes code. No CLA needed.

I don't think contributing back on Blue Oak terms is a condition of the Blue Oak Model License, in the sense of https://www.apache.org/licenses/LICENSE-2.0#contributions. Rather, the Blue Oak Model clearly expresses the expectation that all contributors will do so.

Expressing that expectation in writing can help make a legal case that submitting a contribution for inclusion in the public project implies a license under the same terms. But that's a distant second best to creating a written, public record of each contributor's affirmative intent to license their work under Blue Oak Terms.

That evidence doesn't have to look like a "formal" CLA. It could be as simple as a public comment on the PR:

> I license my contributions under Blue Oak Model 1.0.0.

It could be as simple as having contributors add their names to a THANKS or AUTHORS or CREDITS file in the repo, under a note that everyone licenses BlueOak-1.0.0, with Git commit data showing each contributor added their own name.

I don't know what is meant by "space" here. It's a text file. There's nothing to stop someone listing multiple copyright holders in an MIT license.

In general, having a long list of copyright holders is bad, because it makes it almost impossible in practice to verify that all of the copyright holders actually consent to release their code under the relevant license.

He’s not implying that the space in the file is somehow limited. He’s pointing towards the same problem you are guesturing at in your second paragraph: that “listing” copyright holders really only makes sense when there is only one of them. Any more than that and you raise the legal question: who exactly has copyright on which parts?

When there is more than one copyright holder, you absolutely need language to address that in the license. MIT license has no such language. Apache 2.0 addresses it by requiring CLAs, per-file copyright and attribution notices, etc. Blue Oak addresses it by using terms that start with "Each contributor".

"Each contributor" is meaningless unless you have a list of contributors. If you have a list of contributors, you may as well put it in the license.

No, it's not meaningless. It refers to everyone who has contributed. According to the Blue Oak license, everyone who has contributed licenses their contribution according to the terms of that license. There’s no need to identify them separately, not for licensing purposes anyway. If their code is in there, it’s covered by the license.

No, not unless you have a record that they agreed to contribute their code under that license. There's no magic wording in a license file that can make it possible to get by without keeping a proper record of contributors.

Yes there is such magic wording. You can't use the software without agreeing to the license. It is obviously the case that anyone who contributes is a user of the software. Thus all contributors are bound by the license terms whether or not their names are added to any list. If any contributor were to assert a violation of their copyright, they would themselves be in violation of the license.

Yeah, but you don't know that the person who contributed the code actually holds the copyright to it unless you keep proper records. It's also unclear whether people do in fact automatically agree to all the terms of a license merely by, say, submitting a pull request. Even if the license asserts that this is the case, not all terms of a license are necessarily legally meaningful or enforceable in any given jurisdiction. There isn't a huge amount of case law on this kind of thing, as far as I'm aware.

The bottom line is that any kind of open source license has copyright as its foundation. If you don't have a proper record of the copyright holders, then the license doesn't mean much. You need to know exactly who has the copyright to the code and exactly who is agreeing to release the code under a given license.

I don’t know much about licenses but last week I added a license to one of my GitHub repositories for the first time. GitHub seemed to be heavily pushing MIT as the default.

If the MIT license assumes everyone works at the same place then that seems horrible for GitHub repositories, right?

Horrible for who? Who would it be horrible for, who would it benefit, and who is in a position to decide what the default is? Cui bono?

Horrible in the sense of being an obvious mismatch for how development happens on GitHub, which pretty much exists to make contributions easy across institutional boundaries. No one benefits from the choice of MIT as a GitHub default. It's a quagmire of legal confusion borne out of pure ignorance.

> GitHub, which pretty much exists to make contributions easy across institutional boundaries

No, GitHub exists to somehow benefit the current owners, Microsoft, however they decide is the best way.

> No one benefits from the choice of MIT as a GitHub default.

Actually, there is a good argument to be made that Microsoft actually benefits from MIT being the default, as nickpsecurity pointed out in a sibling comment.

OK I see what you're getting at. Sure, maybe MS is pushing MIT out of sneaky bastardliness. But, it kinda sounds like what you're saying is that as long as it's good for the owner it can't also be horrible.

I mean, my auto shop exists to benefit me however I decide is best, and there is a good argument to be made that I benefit from sabotaging my customers' cars. So what!

> But, it kinda sounds like what you're saying is that as long as it's good for the owner it can't also be horrible.

Oh, that explains the downvotes. No, that’s not what I meant. What I was trying to do was to socratically tease out the strangeness of calling something “horrible for GitHub repositories”, as if GitHub repositories had an inherent purpose.

I'll add to your comment that Microsoft is a known, patent troll. They can give a business something free under MIT, wait until it makes a fortune, and then sue them for same code in patent courts. License like Apache 2.0 give a copyright and patent license for the code. Makes such scenarios impossible.

Whether they'll actually do it or not is an unknown. I'd prefer we default on licenses that nullify the patent risk.

>Bosque programming language is designed for writing code that simple, obvious, and easy to reason about for both humans and machines.

var v: List[Int ?] = List@{1, 2, none, 4};

OK! I think it needs some work. AM I supposed to intuitively know what ? and @ mean?

"Easy to reason about" doesn't mean "Doesn't require you to read any documentation."

Ok, and simple, obvious,?

A project language with a reference implementation written in...TypeScript?


Why is this strange?

This doesn't surprise me. The sample code in the documentation strongly reminded me of Typescript.

Also, there is a slack group dedicated to future programming languages. I am the acting char of the next gen language developer's association, and am trying to get all the next gen language designers to be in communication with each other. Right now there is the Luna project (poland), Red, Parasail, Beads, Elm, Dark, and others. i will be sure to add an entry in our database for Bosque.

>For typed strings, String[T] the compare operator ignores the generic type and is based on the order of the underlying raw string e.g. both arguments are coerced to String.

Why? What even was the point in making them 'typed' then?

Also, what exactly are the relevant language-level details which BOSQUE contributes? It seems more like a large library than anything else.

> Why? What even was the point in making them 'typed' then?

To prevent you from passing a String as a String[Zipcode].

Only thing that caught my eye is the require syntax, which is nice, but then I thought what happens if this contract fails? Its possible you'd want to return false, or raise exception, or log error, or even correct value and continue. So whilst a nice feature, not practical IMO if it would always result in an exception.

I don't think they are runtime checks

How not?

        method makeAutoMove(mark: String[PlayerMark], rnd: Int): Game
        requires !this->hasWinner();

        method makeExplicitMove(x: Int, y: Int, mark: String[PlayerMark]): Game 
        requires !this.board->isCellOccupied(x, y);
If I'm reading it right though, it looks more like it simple doesn't execute the function at all instead of throwing etc. So yet another possible route to deal with an invalid contract.

It could be checked at compile time no?

How would you check them at compile time without using dependent types (at least it doesn't look to me like these are dependent types)?

Reading the publication, I don't see that big a difference to existing purely functional languages. It almost reads like a rediscovery and refinement of the main value propositions of e.g. Haskell.

That said, some of the refinements, especially the (TypeScript-inspired?) record typing and manipulation facilities, look quite pleasant.

i challenge the decision to not have explicit loops. the beauty of the original C construction was that it allowed for 3 events to occur inside each iteration: 1) normal execution of the body, 2) skip over the body but increment the counter, 3) exit the loop. When you have nested loops JS and AS3 let you name the outer loop and break out of it (thus re-introducing the FORTRAN GOTO which although that crank Dijkstra hated so much, occasionally is needed for this purpose). How are you going to stop a loop that might go on too long? sometimes you want to stop early. I don't see how you can stop the map().. or filter() operators. Just because early abort of a loop is not common doesn't mean it doesn't come up; it does inevitably so.

Named loop breakouts aren't the e GOTO Djikatra was concerned aboutvbecause they are still block structured; “harmful” GOTOs are arbitrary, structure-defying jumps. Named loop breakouts do not break the coordinate-assignment capacity that Djikstra takes GOTOs to task for breaking.

> I don't see how you can stop the map().. or filter() operators.

You use an early-terminating operator like find or take. (The general solution is probably Clojure-style transducers, which compose in a way which enables, among other things, plugging termination conditions into an operator which otherwise isn't early terminating.)

Looks a lot like TypeScript to me.

Fix the grammatical error: The Bosque programming language is designed for writing code that simple, obvious, and easy to reason abo

"The Bosque programming language is designed for writing code that simple, obvious, and easy to reason about for both humans and machines. The key design features of the language provide ways to avoid accidental complexity in the development and coding process. The goal is improved developer productivity, increased software quality, and enabling a range of new compilers and developer tooling experiences."

Along with literally every other language. I really wish the splash pages for new languages would cut the boilerplate and just open with a list of the specific traits that make this one different from its peers.

Edit: it appears that this is relatively easy to find after visiting the repository. Still, that opening paragraph is meaningless, and many languages don't even make the worthwhile bits easy to find for those who actively seek them.

http://terralang.org/ does a good job at telling you right away 1. what it is, 2. what it looks like and 3. what makes it different. I could write lots about how the language is great, but I also just realized that its home pages is pretty good for a programming language.

The typed strings feature looks pretty cool.


some poor fellow is going to spend time that he could be using to cure cancer...

Wait til you hear about “forums” on the web.

People spend an incredible amount of time arguing about things in “comments”, when they could be curing cancer.

No, people don't argue about stuff on web forums. That's crazy.

I respectfully disagree, some do.

How dare you disagree? Now I will start a completely unrelated rant about how disagreement is the root cause of all evil and is indeed the real scourge on the face of the earth. (And not multiple programming languages, that some poor soul is falsely led to believe. Just think about it, we have more than one programming language because a misguided fellow disagreed that rocks and stones are the ideal way to program. So you see that disagreement is the reason why we have so many programming languages today. It's always a disagreement that brings suffering and pain.)

Wait, wait, hold on. How dare you disagree with my disagreement and deflect back to programing languages to make a point. Now I am going to read your post carefully and point out spelling and grammar mistakes - but before I do that I have to spend some extra time making sure my post is free of them.

Do you suggest we should stop making new languages? There are a lot of problems with current languages.

Yeah, like how there are so many of them ;)

The thing is that people curing cancer (or doing any other kind of research) famously don't spend their time learning niche languages. Quite frequently they can't program at all. If they can, they usually write some really horrible code in whatever language they learned at school -- mainly because they are too busy doing their research to care about programming.

Programmers, on the other hand, do spend their time learning languages (at least some of them, anyway). People frequently ask me how many programming languages I know. I've lost count of the programming languages I've used on commercial projects (it's well over 20). I don't "know" any of them any more. I stupidly put C++ on my CV the last time I was looking for a job and someone started asking me about Boost. I had to reply, "The STL had just been released the last time I used C++. We thought RogueWave was pretty cool at the time". I mean it's actually a completely different language right now. I need to have a section on my CV for "Can tell you amusing anecdotes for this technology but can't actually use it any more".

However, the important thing is that if you throw tens of thousands of lines of legacy code in any language that is in a style I'm familiar with, I'll be up to speed in a week or two. That's because I'm a professional programmer. It's what I specialise in.

New programming languages are great for a number of reasons. First it moves the state of the art forward without having to be backward compatible. Yeah, the state of the art moves slowly and each new language only adds a tiny bit of improvement, but over time it adds up. You don't want to be using CFront like I was at the beginning of my career. Pretty much any modern language you pick is going to be head and shoulders above that.

But the other thing is that becoming fluent in new languages makes you a better programmer in every language. You see idioms you've never seen before. Techniques that are the bread and butter in one language are unheard of in another language -- mainly because you've got crusty old guys like me who've done the same damn thing every day for 30 or 40 years.

I've actually worked in a physics lab before. They wrote some important papers during the time I worked there and I helped -- by writing the code they needed to analyse their data. That was when I was very young (20???). I'd do a much better job of helping them now, in part because I'd do a better job of taking their hacked up Fortran code and making something that could be maintained long term.

Yeah, you don't need to be a fanboi for some language or other, but you also don't need to be a luddite either. Times change and new things happen. It's one of the fun parts of being a programmer.

> I stupidly put C++ on my CV the last time I was looking for a job and someone started asking me about Boost.

I used C++ as my main language for a few years and have used C++ more recently (although the last time I used it professionally was about 5 years ago now) and last year did a personal project to catch up on all the latest features (basically a project to upgrade my knowledge from C++11 to C++14 and C++17), although I've since given up on C++ since the latest additions are far too complex for me and I'm no longer confident that my code actually works how I want (I'm slowly trying to pick up Rust as a replacement).

My point, though, is that I consider my C++ skills to be above average, or at least, above passable, and yet I have never used Boost, have no intentions of ever using boost if I do use C++ (between C++17's standard library features and plenty of easy to use header only libraries, I just don't see the need for Boost for any projects I've ever used C++ on), so I wouldn't be able to answer any questions on Boost either.

Because Bosque has Visual Studio integration, I suspect it's purpose is related to that. A DSL for the purpose of integrating its abstractions into existing mainstream tools...a language built to investigate and solve Microsoft's problems. Maybe it becomes mainstream. But like most programming languages, it's unlikely because most individuals and organizations aren't trying to solve the problem it was built to solve.

Applications are open for YC Summer 2021

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