
Bosque Programming Language - matt_d
https://www.microsoft.com/en-us/research/project/bosque-programming-language/
======
mrkmarron
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.

~~~
reikonomusha
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...](http://www.cs.nott.ac.uk/~pszcah/G51ISS/Documents/NoSilverBullet.html)

~~~
azhenley
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!

~~~
awild
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.

~~~
vnorilo
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?

------
cabalamat
Some comments on the code, based on Tictactoe example
([https://github.com/Microsoft/BosqueLanguage/blob/master/docs...](https://github.com/Microsoft/BosqueLanguage/blob/master/docs/tictactoe.md)):

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' | ' ';

~~~
GordonS
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.

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

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

    
    
        point<~(y=value)
    

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.

~~~
ken
<~ 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.

~~~
pmontra
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.

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

~~~
pmontra
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"
        "abc"
        iex(2)> String.replace(s, "b", "B")
        "aBc"
        iex(3)> s
        "abc"
    

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")
        "aBc"
        iex(5)> s
        "aBc"

------
mhd
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...

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

------
mshockwave
> 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

~~~
emmanueloga_
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.

[https://en.wikipedia.org/wiki/Undefined_behavior#Risks](https://en.wikipedia.org/wiki/Undefined_behavior#Risks)

~~~
dkersten
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!"_

~~~
readams
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.

------
mcintyre1994
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...](https://dotty.epfl.ch/docs/reference/other-new-
features/opaques.html)

~~~
mrkmarron
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.

~~~
mcintyre1994
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.

------
ptrott2017
Direct link to github repository:

[https://github.com/Microsoft/BosqueLanguage](https://github.com/Microsoft/BosqueLanguage)

------
bfrydl
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.

------
velcrovan
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.

[https://writing.kemitchell.com/2019/03/09/Deprecation-
Notice...](https://writing.kemitchell.com/2019/03/09/Deprecation-Notice.html)

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

~~~
foldr
>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.

~~~
hobofan
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".

~~~
foldr
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.

~~~
velcrovan
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.

~~~
foldr
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.

~~~
velcrovan
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".

~~~
foldr
"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.

~~~
velcrovan
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.

~~~
foldr
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.

~~~
velcrovan
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.

~~~
foldr
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.

------
quadcore
Paper: [https://www.microsoft.com/en-
us/research/uploads/prod/2019/0...](https://www.microsoft.com/en-
us/research/uploads/prod/2019/04/beyond_structured_report_v2.pdf)

------
SlowRobotAhead
>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?

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

~~~
SlowRobotAhead
Ok, and _simple, obvious,_?

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

O.o

~~~
bartschuijt
See also chapter 3 in the paper: [https://www.microsoft.com/en-
us/research/uploads/prod/2019/0...](https://www.microsoft.com/en-
us/research/uploads/prod/2019/04/beyond_structured_report_v2.pdf)

------
magicmouse
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.

------
jsjolen
>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.

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

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

------
hacker_9
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.

~~~
UK-AL
I don't think they are runtime checks

~~~
hacker_9
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.

~~~
asimpletune
It could be checked at compile time no?

~~~
Sean1708
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)?

------
mpartel
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.

------
magicmouse
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.

~~~
dragonwriter
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.)

------
quickthrower2
Looks a lot like TypeScript to me.

------
magicmouse
the slack group is
[https://futureofcoding.slack.com/](https://futureofcoding.slack.com/)

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

------
_bxg1
"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.

~~~
DarkWiiPlayer
[http://terralang.org/](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.

