Microsoft Debuts Bosque, a New Programming Language With No Loops, Inspired by TypeScript (theregister.co.uk) 261
Microsoft has introduced a new open source programming language called Bosque that aspires to be simple and easy to understand by embracing algebraic operations and shunning techniques that create complexity. From a report: Bosque was inspired by the syntax and types of TypeScript and the semantics of ML and Node/JavaScript. It's the brainchild of Microsoft computer scientist Mark Marron, who describes the language as an effort to move beyond the structured programming model that became popular in the 1970s. The structured programming paradigm, in which flow control is managed with loops, conditionals, and subroutines, became popular after a 1968 paper titled "Go To Statement Considered Harmful" by computer scientist Edsger Dijkstra. Marron believes we can do better by getting rid of sources of complexity like loops, mutable state, and reference equality. The result is Bosque, which represents a programming paradigm that Marron, in a paper he wrote, calls "regularized programming."
I hate code-and-pray (Score:4, Interesting)
Re: I hate code-and-pray (Score:4, Funny)
So, if a bug occurs between 37,446,468 levels deep in recursion and 77,894,223 levels deep, depending on number of clock cycles and number of cache L2 hits, that would be easy to debug?!?
Either you're the world's greatest debugger, or you're insane.
(or both)
Re: (Score:3)
He did say *can* be easier to debug. When recursion is appropriate, a decent programmer might find it simpler to debug. In my experience, those occasions are much rarer than those that call for a loop. And if a non-decent programmer ever has to look at your code, the recursion will cause their brain to hemorrhage.
Re: (Score:2)
The problem is in language, what needs to be done is see how code looks when inside a normal text document, and how it looks when compared to maths, readable is not readable in relation to understood coding methods, readable is how it looks compared to normal text or normal maths. How it relates, how it is logically structured based on those two other languages, how you can read English, read maths and read code. Coders keep doing from a perspective of already being coders, they is the wrong approach, it is
Re: (Score:2)
consider English the coding language
One word: COBOL.
Re: (Score:2)
You've expressed contradictory goals. Plain language is highly contextual and redundant, containing a lot of ambiguity. Math is highly formal and rigid.
Most procedural languages are somewhere in the middle. More expressive than math, while retaining the formality necessary to be unambiguously parsed.
Re: (Score:2)
For a historical example:
Will no one rid me of this turbulent priest?
Re: I hate code-and-pray (Score:2)
Sure, there are algorithms more neatly expressed with recursion. There are also algorithms more neatly expressed with loops. When you deal with the latter in a functional language, you can just end up simulating mutable state by passing lots of arguments in the recursion, and you get all the bug possibilities of mutable state plus a loss of readability.
Re: (Score:3)
Re: (Score:2)
Re: (Score:3)
The line of code where the bug ocures is the same, regardless how deep the recursion went.
Re: (Score:2)
Iteration actually does impede debugability a lot. Even with conditional breakpoints, debugging an issue that say happens between iterations 37,446,468 and 77,894,223 of a loop, but depends on the number of clock cycles and the number of L2 cache hits, can be very difficult. And before you say that that sort of a situation can't or doesn't happen, you're absolutely wrong. That scenario is a simplification of a problem I once debugged.
So you think hiding the iteration at a level inaccessible to the programmer will make that easier to debug ?
Re: (Score:2)
Re: (Score:2)
No way you guys are going to catch up to C++ in performance, leave alone C or FORTRAN.
For most programs, optimizing for run-time performance is not a priority.
If it takes a week to write it, and 20 seconds to run it, reducing the 1st delay is far more important than reducing the 2nd.
Re: I hate code-and-pray (Score:2)
Re: (Score:2)
If you can knock 10 seconds off a kernel routine ...
There is no such kernel routine
As always premature optimization is evil, but claims that development time trumps any benefits in all cases is absurd.
He did not say "in all cases", nitpicker.
Re: (Score:2)
The difference between you and me is pretty simple, I only call morons morons ...
Next time simply pick better examples ... e.g. the loading time of Word or something similar, can't be so hard.
Re: I hate code-and-pray (Score:2)
Re: I hate code-and-pray (Score:2)
Re: I hate code-and-pray (Score:2)
Re: (Score:2)
Re: (Score:2)
Count modules and programs by the revenue they generate, or the cpu cycles they rake up, optimizing for development time, not the run time would not be good for "most programs".
The code I manage rakes up probably 50,000 days of processor time every year [*] My module takes less than 1% of the total consu
Re: I hate code-and-pray (Score:2)
This.
The best practice is to optimize the codebase as a whole for security, stability, clarity, obviousness, maintainability, etc. Then profile the running system and find the bottlenecks. Optimize those bottlenecks for speed using non-obvious code if necessary. Leave clear comments explaining why that little bit of funky code is in there, and suggesting future programmers approach it with caution.
Re: (Score:3)
Replacing loops with recursion, like many functional languages and modern languages like Rust do, can make debugging much simpler. Tail recursion optimizations
Iteration and tail recursion are the same damn thing. They're just spelled differently. Syntax suger can sometime help debugability, to be sure, but there's almost no difference in the actual code between a for loop and the equivalent looping construction a functional language ("let" or whatever).
When you have the same number of lines of code, that compile to the same object, any claims of difference in debugability are pretty far-fetched.
"Imutability" is its own fad, and not a very good one. Too much mu
Re: (Score:2)
Iteration and tail recursion are the same damn thing. They're just spelled differently.
Except that most programmers understand iteration better than they understand recursion.
Recursion makes sense for algorithms that deal with recursive data structures such as trees and graphs. But using recursion to walk a linked list or scan an array is just pointless obfuscation. Sure, the compiler can clean it up, and generate efficient code, but why not just write clean code to begin with?
Re: (Score:2)
Explicit loops are rare anyhow. What most people end up writing these days are "list comprehensions". e.g.
customerList.forEach(customer => {
if ((customer.timeLastAnnoyed - now) > ANNOYANCE_THRESHOLD)) {
sendMarketingEmail(customer);
customer.timeLastAnnoyed = now;
}
});
Is that iterative? Recursive? It has a lambda, so it must be good, right? I prefer that style most of the time, actually, but to not have the primi
Re: (Score:2)
Is that iterative? Recursive?
It is clearly iterative.
You are iterating through the list with "forEach" and there is no recursion at all.
Re: (Score:2)
Re: (Score:2)
Wrong, you have no idea whether it's iterative or recursive. The mechanism is hidden within customerList.forEach.
Who cares how the compiler implements it?
You should chose either iterative or recursive based on readability of the code.
If you care about efficiency, then avoid recursion, since it is always going to be slower than an equivalent iterative implementation (unless the compiler optimizes out the recursion).
Re: I hate code-and-pray (Score:2)
If you care about efficiency, then avoid recursion, since it is always going to be slower than an equivalent iterative implementation (unless the compiler optimizes out the recursion).
In other words, "always use recursion and your quality compiler will always do the right thing".
Re: (Score:2)
In other words, "always use recursion and your quality compiler will always do the right thing".
Not true. Very few instances of recursion will be "fixed" by the compiler. Tail recursion usually is, but most other uses of recursion are not.
Here is a horribly inefficient recursive implementation to compute a Fibonacci number. Compile it with "gcc -O3 -S" and it is compiled "as is".
long
fib(long n)
{
if (n < 3) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
Re: (Score:2)
Re: (Score:2)
Re: (Score:2)
The whole idea of list comprehensions comes from Lisp, though. Other languages adopted it slowly over time, needing to add some lambda syntax to do so. But that's sort of my point: there's no damn difference, except for the syntax sugar.
Re: (Score:2)
Except that most programmers understand iteration better than they understand recursion.
Is it legal to call someone that doesn't understand recursion a programmer?
Re: (Score:2)
Re: (Score:2)
Sure, the compiler can clean it up, and generate efficient code, but why not just write clean code to begin with?
Among other things (one of which I mentioned above, and which also often makes recursion *cleaner* than loops), loops are not modular, but recursion is. You don't have to transfer control within a lexically delimited block of code; you can have an arbitrary number of named states, or even have it extensible without rewriting one huge loop, whether that loop is a parser, or an intepreter, or anything else that would be rather difficult to scale with a huge loop over a block of code.
Also, higher-order functi
Re: (Score:2)
Re: (Score:2)
Tail recursion is re-assign and jump. The re-assign is still there. The tail call is the state change for all if the variables therein.
Re: (Score:2)
Re: (Score:2)
I guess it's subjective. There's little difference between expressing the change in a for statement or in a tail call. To me, as soon as there's more than one variable changing, I'd much rather assign them by name than by position - I like the explicitness. But I know people who prefer the terseness of the positional approach, since the DIE will show you the name anyway.
Re: (Score:3)
Re:I hate code-and-pray (Score:5, Insightful)
If it reduces or eliminates mutable state, it's very easy to debug
No, because all Turing complete programming languages can be used to create a universal machine for a different language. So you can simply take a C++ program, and run it inside a suitable Bosque framework, which means that you will inherit all the original C++ problems and bugs as well.
Or, in general terms, you can create similar bugs in every kind of programming language.
Then discard Turing completeness (Score:2)
all Turing complete programming languages can be used to create a universal machine for a different language.
Then perhaps it's wise to discard Turing completeness in some applications. One might deliberately design a system to decide languages at some level of complexity between context-free languages and context-sensitive languages, without needing to head up to the recursively enumerable languages that require Turing completeness. It's impossible to decide more than a context-sensitive language on a physical computer anyway, as a physical computer with finite memory is analogous to a linear bounded automaton, wh
It's actually worse than that (Score:5, Interesting)
You see, while the source code is human-readable, the machine code is generally not. And we're sitting on decades of cycles of machine code generating machine code, over and over again. To convert source code into machine runnable code, you need a compiler. And while that compiler may be distributed as source code, you still need a compiler to compile that source code into a compiler. The Gnu C Compiler version 8 was compiled using GCC version 7. Version 7 was compiled using version 6. Version 6 was compiled from version 5. And so on. At some point, you were forced to run machine code that you trust, and don't have access to the source code to.
If a backdoor were inserted into the compiler machine code at some earlier stage, then it could propagate itself without ever showing up in the source code. The only way to avoid this is to hand-write your own rudimentary compiler directly in machine code. Then bootstrap that to compile a more sophisticated compiler. Then use that compiler to compile the latest version of GCC (or whatever other language compiler you want).
While the idea was proposed for backdoors, the same concept works for bugs. If a bug were introduced into the compiler machine code so that it, say, has a special case exception to return 2+2 = 5, then it would dutifully propagate that bug into all programs and compilers produced with it. So if the Bosque compiler was originally compiled with a C compiler, it would inherit any such bugs present in the C compiler. As would any future Bosque compilers compiled from that original Bosque compiler.
Re:It's actually worse than that (Score:5, Informative)
It was Ken Thompson who talked about this (and largely popularized awareness of this as a concept), in an ACM talk in 1984 he called "Reflections on Trusting Trust"
A fully copy is at https://www.win.tue.nl/~aeb/linux/hh/thompson/trust.html [win.tue.nl]
Re: (Score:2)
Fairly easy to get around the supposed library infection you begin at step 3, though: compile the library from source and then you won't have the infected copy. Also, you could compile the library from the source (which had the defect reverted from it) and compare the resultant binary to the one that was provided, which would produce a discrepancy which you could then investigate.
The assumes you have a uncompromised compiler, of course.
Re: It's actually worse than that (Score:2)
You might enjoy this article, about "Fully Countering Trusting Trust through Diverse Double-Compiling":
https://dwheeler.com/trusting-... [dwheeler.com]
Re: It's actually worse than that (Score:2)
The only way to avoid this is to hand-write your own rudimentary compiler directly in machine code.
I'm pretty sure that's an unnecessary overkill. If you write your own compiler *from scratch*, the "infected" compiler would need some prety strong AI to identify that you're writing a compiler, as opposed to other kinds of data processing programs (which a compiler is, as it takes an input file and generares an output file). Since such a thing doesn't exist, such an "infected" compiler can't reliably distinguish all compilers from all non-compilers, generally speaking.
Re: (Score:2)
all the infected compiler must do is look at the source file path
Sure, by looking at "/home/l33th4x0r/pinkiepie/transmogrify.c", you can tell it's the source code of the bootstrapping Pinkie Pie compiler that I just wrote. That's certainly going to work!
All versions pf GCC for example, for the last 30 years, is built from source in a file hierarchy rooted in a directory containing the substring gcc.
Well it's a good thing, then, that you're not building GCC with your infected compiler, but rather a completely different compiler that the author of the exploit couldn't even have known about.
The same is true of clang, and almost every other compiler or interpreter.
This is the first time I'm hearing about clang or any other compiler or interpreter being built from source in a file hierarchy ro
Reproducible builds (Score:2)
Defeating this kind of "binary-backdoored compiler with non backdoored source code" is among the key reasons for reproducible build.
Basically :
- you take a large collection of C compilers for various platforms of your choice.
- you take known-good, well reviewed, "many eyeballs looking making bugs shallow" (Linus' Law by ESR) compiler written in *C* (e.g.: GCC)
- you compile your opensource compiler with as many of the C-compiles gathered in point 1
- you end up with a large collection of executable programs,
Re: (Score:2)
You write a business rules interpreter and invite the accountants to define their own rules.
Re: (Score:2)
This almost sounds like a jab at PICK
Re: (Score:2)
The examples on the github page looked pretty mutable.
They just called them 'updatable variables'.
function abs(x: Int): Int { //declare updatable variable with initial value //update the variable
var! sign = 1;
if(x 0) {
sign = -1;
}
return x * sign;
}
and
"Variables declared as mutable, using the var! syntax, can be modified by later assignmen
Simple, Capable, Debuggable (Score:5, Insightful)
I'm not sure you can pick one with Bosque (Score:2)
I'm guessing it's capable, but I don't see simplicity or it being easily debuggable.
Re: (Score:2)
In other news, (Score:5, Funny)
There will likely be job offers in the next few weeks asking for a couple years of experience with this new programming language.
Re:In other news, (Score:5, Funny)
And there will be people applying with 5 years experience already too :P
Re: (Score:3)
I heard the story about someone who had started working with Ruby on Rails right as it was first released. He applied for a job working with it, and they asked for some number of years experience, which was like a year more than he had. He applied anyway, and when he was rejected for someone with more experience, he challenged them--who possibly had more experience with it than he did, since he had worked with it since release. Answer: The guy who wrote it. I don't know if this was true or not, but it
Re: (Score:2)
=D
no mod points, so have a smiley. happy friday.
Either confused HR or a desire to poach (Score:2)
I've concluded that a job posting requiring years of experience with a weeks- or months-old technology have three aims:
1. IT wants someone with however many years of experience with programming languages in that paradigm, including at least some experience with the language in question. But HR got confused when it worded the job posting.
2. It's an excuse to poach someone who worked on the technology before it was first published. For example, "3 years experience with Java" when Java was 2 months old means "
Job postings only for show to meet letter of law (Score:2)
I might apply there if I was out of other options
Fresh out of university without enough money to relocate to a city with more demand for your skills is one example.
I think there might not be an open job posting at all in this case, but a discreet inquiry if the person would be amenable to switching.
There might be some anti-cronyism regulation against "no-bid" contracts or hiring practices. So to meet the letter of the law when poaching a specific person, HR posts a job posting, and because this job posting is only for show, it is specially crafted to apply only to the person being poached.
The Functional Trap (Score:5, Interesting)
You revel in the joy of freedom from end effects and state errors.
Then you come up against a brick wall - "How the hell do I do that in a functional language?"
I have a book called "Functions Data Structures". It's actually a book on all the data structures that you cannot implement in a function language.
Before long you cheat and link in a loop with a conditional in C just to remain sane.
I've had great success with functional languages where the target domain is functional - E.G. Functional HDLs like confluence. Digital logic is functional. You can describe it functionally and it's way better than System Verilog.
Re: (Score:2)
Re: (Score:2)
Immutability is a requirement for a purely functional data structure. That's not a requirement for Turing completeness. That's what makes the difference.
https://en.wikipedia.org/wiki/... [wikipedia.org]
Re: (Score:2)
Yeah, you can say that about any language.
> C is great just don't fuck up
> C++ is great, just don't use all the features
> java is great, just don't use it
> golang is great, just pray google keeps supporting it
Re: (Score:2)
Typo : Purely Functional Data Structures.
https://www.amazon.com/Purely-... [amazon.com]
Re: (Score:2)
I prefer languages like Python where I can choose the functional style where it's appropriate and the imperative style where appropriate.
New functional language. Is that it? (Score:4, Interesting)
Admittedly I haven't delved into it very far yet, but this looks like a standard functional language. The ideas he talks about have been around for ages. That does mean I am confident that they work, more so than the usual "new paradigm".
Haskell that compiles is a lot closer to working than C would be; getting it to compile is a lot harder (debugging takes place before running) and getting that last few percent (correct output) can be a massive pain: not being able to crash doesn't always help to find problems, especially without a useful debugger. Does Bosque improve on that? Does it have a good FFI (a common failing)? Can it support UI's (huge pain with most functional languages; workarounds are mostly ill-fitting bandaids.)
I'm trying to find a reason to care here.
Re: (Score:2)
Re: (Score:2)
My company has some legacy Haskell code, written by a couple of programmers who were die-hard evangelists for the language. The irony is, they wrote TERRIBLE code, hard-coding constants that should have been configuration settings, hard-coding HTML and SQL strings, and everything else you can think of. I hope there are better Haskell programmers out there, because what I've seen...stinks.
A loop my any other name... (Score:2)
Simple to understand? (Score:5, Interesting)
Seriously?
v |> filter(fn(x) => x != none) |> map[Int](fn(x) => x*x)
WTF? I hardly call that simple to understand...
Re:Simple to understand? (Score:5, Interesting)
It's the sort of thing that programming language designers seem to love. I've never understood the apparent loathing they have for simple, readable loops. I think maybe because loops are "conceptually" ugly, albeit infinitely practical. So, they keep trying to refine them into something more elegant, but IMO, end up making things more complex and opaque.
Re: (Score:3)
Re: (Score:2)
It's the sort of thing that programming language designers seem to love. I've never understood the apparent loathing they have for simple, readable loops. I think maybe because loops are "conceptually" ugly, albeit infinitely practical. So, they keep trying to refine them into something more elegant, but IMO, end up making things more complex and opaque.
This seems to yearn for the FORTRAN era-definition of simplicity, which meant "it looks like a mathematical statement" to language designers. I suppose, if you were giving a math lecture, v |> filter(fn(x) => x!= none) |> map[Int](fn(x) => x*x) could stand in for, "Let v(<X>) => <Y> map all non-nil elements to their squared integral equivalents" or somesuch. (I'm being sloppy with notation here because it's been years, I'm busy, and I kinda noped out of the Bosque README.md docume
Re: (Score:2)
As someone who does both C++ and Erlang, loopless languages have a very simple advantage: the loop variables are only changed at the end of the loop or the loop is made using a lambda inside a function with a predictable behavior.
Re: (Score:2)
Don't knock it till you try it.
This works quite well when you are applying several transformations on collections.
At that point, loops start to feel like GOTOs.
There are also other benefits. In some languages, you can effortlessly parallelize streams written fluently like this.
Other post: https://developers.slashdot.or... [slashdot.org]
Re:Simple to understand? (Score:4, Funny)
Depends on whether you're a perl programmer or not.
Re: (Score:2)
Re: (Score:2)
Slashdot is a technical discussion site. You should know what Perl [wikipedia.org] is. You could also very easily Google it.
When you're interacting with a community, it's important to know how to speak the language, or at least being willing to learn.
map (Score:2)
oh I see ... map (and grep) two old Perl paradigms that I have loved.
Re: (Score:2)
I find that simpler, more natural and "fluent".
It cognitively scales much better to read linearly, left to right, than nesting.
It is not a good fit for everything, but this approach is quite common in data analysis code. You get used to it quite quickly.
map, filter, curry and a pipe operator are bliss when you are doing a long series of transformations. Very compact too.
R community switched to dplyr. Everyone seems to love it.
https://github.com/hadley/dply... [github.com]
Python has some libraries, minus the operator.
But
Re: (Score:2)
You're clearly not a real programmer if you can't understand that. Why, any monkey could have written that code! (Maybe one did!)
Re: (Score:2)
Re: Simple to understand? (Score:2)
Sorry, this is trying to eliminate complexity? (Score:4, Insightful)
As I read through the description of the language in the overview.md, it seems to me that Marron took the things that he didn't like about existing languages and changed them into something he does without consulting anybody.
So where is it is less complex for him, it seems like it will be more complex (and unnatural) for the rest of us.
Unintended complexity is the enemy, is the point (Score:3)
He's trying to eliminate _unintended_ complexity, the kind of complexity that comes by having to use language elements that don't directly contribute to solving the problem, they are essentially just scaffolding upon/through which solves the actual problem. One example is looping semantics. In other languages, you have to write some scaffolding to marshal up the items in the thing you're iterating through, and then there's what you want to do with each item. He says he studied all the different kinds of thi
Re: (Score:2)
Did you look at the hideous Tic-Tac-Toe example [github.com] ?
Modern version of APL? (Score:3)
The more I read of the overview and see people's comments, the more it reminds me of APL (https://en.wikipedia.org/wiki/APL_(programming_language))
Maybe it will be efficient to write but I don't see it being easy to read/follow/debug.
Re: (Score:2)
Marron and Dijkstra (Score:3)
Example code looks terrible (Score:2)
Just use haskell or one of the other existing ones. Hey, MS already has their own called F#, why not use that?
What an ugly language?! (Score:2)
I thought obscure special characters as operators and sigils like @ had died with PERL? And what actually is var! supposed to mean, or more precisely: var without the ! ? (Yeah I know what it means ... var is a variable which is constant, so much to "variable" and var! declares a variable you actually can modify ... silly )
However: I like the name :P
Scheme/LISP (Score:2)
This looks like a refresh of LISP/Scheme. Before they eventually added loops. They used tail recursion for iteration.
Re: (Score:2)
Re: (Score:2)
It's basically C with improved structs and generic code and some guarantees around memory safety.
You can write "clever" aka shitty code in any language including C, and especially C++.
Re: (Score:2)
Re: (Score:2)
BTW isn't that what Python and/or Visual BASIC is for? </sarcasm>