1
I Use This!
Inactive

News

Analyzed about 20 hours ago. based on code collected 2 days ago.
Posted over 9 years ago
A common complaint about dynamic languages is the lack of type safety, and that the only solution is a complete formal one. Interestingly there really does seem to be a very binary view about type systems. So let’s get to the bottom of that before we ... [More] discuss the heuristic approach. Static typing is largely a good thing because it helps us to spot bugs before our code goes into production and reduces (in theory) the amount of unit testing required to find bugs. The received wisdom is that unless you use a formally proven post-doctorate level type system then your code is sloppy and weak. In reality this is a complex subject within a huge terrain of possible solutions and that many answers are appropriate for many different situations. The problem with the simple binary viewpoint is that it does not actually allow for trade off of the extra work involved in maintaining a type system and therefore in getting it’s rewards. This extra effort if used in systems that require minimal type safety can cause less experienced developers to try and throw the baby out with the bathwater - and stick to only using languages with a very loose type system. I think this somewhat illusory dichotomy can be removed or weakened with the application of a metaphor of real world contracts. If I lend my friend £20 there is an implied contract that she will return that money by her next paycheck. If she doesn’t then my trust in her is weakened but hey I’m only down £20. However if I then went to court over my £20 (like I would!) I have nothing but my word to rely upon. This is the level of type safety we would find in, say, JavaScript. Most of the time it works - there’s little consequence (in the browser!) if it doesn’t and it’s a quick simple friendly solution that doesn’t slow people’s lives down. Now let’s go to the other extreme. I am writing a contract between two multinational corporations for about 3 squidgillion dollars. If I make a mistake my job, career and possibly the jobs and careers at my entire company could be at stake. So I write a contract with a team of a 50 lawyers and produce a 200 page contract which absolutely nobody but a corporate lawyer understands. However there is pretty much no way anyone could wriggle out of that contract. This is the land of formal languages and languages with advanced type systems like Haskell. Now what interests me is that there is a huge gap in between, a vast spectrum of possibilities. Contracts for car hire, EULAs, privacy policies, employment contracts and so forth. In these cases I do want some formality to protect myself - because these people aren’t close friends that I trust and the consequences can be expensive. However they need to legible to both parties without a team of 50 specialist lawyers because, hey we have other things to do in our lives. Each language, each project and each developer puts there stake in the ground as to how much or little type safety they want. For wiser, older developers this is usually an educated trade off - for the rest it’s a flame war over languages and religious technical beliefs. So where does DollarScript lie on this continuum? Well I’m taking a fairly radical approach and allowing the type system to learn from experience. Heh? DollarScript learns from runtime usage what types are usually returned from expressions, modules, resources etc. for any given set of inputs. It then warns you if your code depends on a type that in all probability is wrong. The huge advantage of this approach is that you get a lot of the type safety of a statically typed language without the constant fussing around with importing type declarations from external resources. It also means that type safety can be applied in places that a static type system cannot calculate the type - i.e. from an external service. We’re not enforcing a type system, just warning you if you appear to be breaching it. This gives 98% of the result for 2% of the effort. To go back to our analogy - this is saying that our contracts are based on what other people are currently using as contracts. We’re taking a calculated risk that those borrowed contracts may be flawed but we’re getting the vast majority of the safety for a fraction of the cost/effort. So here is this in action: i= "1+2" // this is never executed but we will get a type warning for it anyway // during the initial parse phase. The error will be 'Type assertion may fail, // expected INTEGER most likely type is STRING (100%)'. if(false) { <Integer> c= 3 + i } The above example is really too over simplified to be useful (better ones to come) but it does illustrate the principle that static analysis is being performed - and that analysis is based on past experience. In this case the experience of what happens when a String is added to an Integer. The <Integer> represents a type assertion during assignment. Of course the above example could easily be hardcoded into the language, but what if i came from an external service? Or a function from a separate module? Without a reasonable degree of type annotation the type system would quickly weaken. DollarScript avoids this by using a statistical approach to predicting the type from previous runtime usage. If I can emphasize this a little further, a type system is like the Travelling Salesperson Problem, that is, a complete formal solution with 100% accuracy is extremely (in that case NP) hard, yet the 98% solution is relatively fast and simple to achieve. The actual prediction mechanism in DollarScript is pluggable - allowing for anything from simple statistics to machine learning to be used to increase the accuracy of predictions. Naturally in later versions of DollarScript this mechanism will be switched off outside of development environments. I know this an incredibly brief introduction - but I really wanted to get some early thoughts and feedback (please no religious feedback, thanks - your chosen programming language is great - keep using it!). [Less]
Posted over 9 years ago
It’s good to be wary about 3 line code, wow examples. But it’s hard not to want to show off the reactive aspects of DollarScript, so here goes: server= socketio://127.0.0.1:8092/bulletin?eventType=chatevent message *= server ("chatevent" : message) ... [More] publish server Let’s break it down. server= socketio://127.0.0.1:8092/bulletin?eventType=chatevent This simply sets the variable server to be the url of the server we’re going to create. The important parts are the hostname, socket and the type of event we’re interested in - in this case chatevent. message *= server Now we have the magic, the *= is the subscriptive assignment operator. This is essential syntactic sugar to say subscribe to server and when a new value is available assign it to message. ("chatevent" : message) publish server Finally we have the reactive part. The first thing we do is create a ‘pair’, a pair is a map with a single key/value entry created using :. The key is the type of event we are going to send, the value is the actual message itself. Because we have the variable message in this expression any change to message will cause the expression to be re-evaluated causing the pair to be published using the publish operator to our previously defined server. And that my friends is it. It’s obviously a very simple example, however I feel it amply illustrates the value of the reactive side of Dollar. This is a working example, you’ll also need the client code [Less]
Posted over 9 years ago
Support for functional programming is now included in DollarScript, this will be widened as the language is developed. For now it is provided by the pure operator. This signals that an expression or declaration is a pure expression or function. In ... [More] this example we’re declaring reverse to be an expression that reverses two values from a supplied array. Because we declare it as pure the expression supplied must also be pure. To understand what a pure function is please read the Wikipedia entry. Basically it prohibits the reading of external state or the setting of external state. We next swap [2,1] within a newly created pure expression, which is subsequently assigned to a. If reverse had not been declared pure it would not be allowed within the pure expression. pure reverse := [$1[1],$1[0]] a= pure { reverse([2,1]) } Note some builtin functions are not themselves pure and will trigger parser errors if you attempt to use them in a pure expression. Take DATE() for example which supplies an external state (the computers clock). [Less]
Posted over 9 years ago
The 0.1.0 experimental release of DollarScript is ready to download in Bintray. This release is just to give you a taste of what Dollar is all about and to encourage hackers to feedback on language features. Please let me know of bugs, ideas etc. I’m @neilellis on Twitter or email [email protected] - good luck!