A Conversation with Alan Kay:
Big talk with the creator of smalltalk - and much more
When you want to gain a historical perspective on personal computing and programming languages, why not turn to one of the industry’s preeminent pioneers? That would be Alan Kay, winner of last year’s Turing Award for leading the team that invented Smalltalk, as well as for his fundamental contributions to personal computing. Kay was one of the founders of the Xerox Palo Alto Research Center (PARC), where he led one of several groups that together developed modern workstations (and the forerunners of the Macintosh), Smalltalk, the overlapping window interface, desktop publishing, the Ethernet, laser printing, and network client-servers.
A Conversation with Arthur Whitney:
Can code ever be too terse? The designer of the K and Q languages discusses this question and many more with Queue editorial board member Bryan Cantrill.
When it comes to programming languages, Arthur Whitney is a man of few words. The languages he has designed, such as A, K, and Q, are known for their terse, often cryptic syntax and tendency to use single ASCII characters instead of reserved words. While these languages may mystify those used to wordier languages such as Java, their speed and efficiency has made them popular with engineers on Wall Street.
A New Objective-C Runtime: from Research to Production:
Backward compatibility always trumps new features.
The path from the research prototype (Étoilé runtime) to the shipping version (GNUstep runtime) involved a complete rewrite and redesign. This isn’t necessarily a bad thing: part of the point of building a prototype is to learn what makes sense and what doesn’t, and to investigate what is feasible in a world where you control the entire system, but not necessarily in production.
ACID: My Personal:
How could I miss such a simple thing?
I had a chance recently to chat with my old friend, Andreas Reuter, the inventor of ACID. He and his Ph.D. advisor, Theo Härder, coined the term in their famous 1983 paper, Principles of Transaction-Oriented Database Recovery. I had blinders on after almost four decades of seeing C based on my assumptions. One big lesson for me is to work hard to ALWAYS question your assumptions. Try hard to surround yourself with curious and passionate people, both young and old, who will challenge you and try to dislodge your blinders.
C Is Not a Low-level Language:
Your computer is not a fast PDP-11.
In the wake of the recent Meltdown and Spectre vulnerabilities, it’s worth spending some time looking at root causes. Both of these vulnerabilities involved processors speculatively executing instructions past some kind of access check and allowing the attacker to observe the results via a side channel. The features that led to these vulnerabilities, along with several others, were added to let C programmers continue to believe they were programming in a low-level language, when this hasn’t been the case for decades.
Catch-23: The New C Standard Sets the World on Fire
A new major revision of the C programming language standard is nearly upon us. C23 introduces pleasant conveniences, retains venerable traps for the unwary, and innovates a gratuitous catastrophe. A few steps forward, much sideways shuffling, and a drunken backward stumble into the fireplace come together in the official dance of C standardization, the Whiskey Tango Foxtrot.
Creating Languages in Racket:
Sometimes you just have to make a better mousetrap.
Choosing the right tool for a simple job is easy: a screwdriver is usually the best option when you need to change the battery in a toy, and grep is the obvious choice to check for a word in a text document. For more complex tasks, the choice of tool is rarely so straightforward--all the more so for a programming task, where programmers have an unparalleled ability to construct their own tools. Programmers frequently solve programming problems by creating new tool programs, such as scripts that generate source code from tables of data.
DSL for the Uninitiated:
Domain-specific languages bridge the semantic gap in programming.
One of the main reasons why software projects fail is the lack of communication between the business users, who actually know the problem domain, and the developers who design and implement the software model. Business users understand the domain terminology, and they speak a vocabulary that may be quite alien to the software people; it’s no wonder that the communication model can break down right at the beginning of the project life cycle.
Design Exploration through Code-generating DSLs:
High-level DSLs for low-level programming
DSLs (domain-specific languages) make programs shorter and easier to write. They can be stand-alone - for example, LaTeX, Makefiles, and SQL - or they can be embedded in a host language. You might think that DSLs embedded in high-level languages would be abstract or mathematically oriented, far from the nitty-gritty of low-level programming. This is not the case. This article demonstrates how high-level EDSLs (embedded DSLs) really can ease low-level programming. There is no contradiction.
Domain-specific Languages and Code Synthesis Using Haskell:
Looking at embedded DSLs
There are many ways to give instructions to a computer: an electrical engineer might write a MATLAB program; a database administrator might write an SQL script; a hardware engineer might write in Verilog; and an accountant might write a spreadsheet with embedded formulas. Aside from the difference in language used in each of these examples, there is an important difference in form and idiom. Each uses a language customized to the job at hand, and each builds computational requests in a form both familiar and productive for programmers (although accountants may not think of themselves as programmers).
Extensible Programming for the 21st Century:
Is an open, more flexible programming environment just around the corner?
In his keynote address at OOPSLA ’98, Sun Microsystems Fellow Guy L. Steele Jr. said, “From now on, a main goal in designing a language should be to plan for growth.” Functions, user-defined types, operator overloading, and generics (such as C++ templates) are no longer enough: tomorrow’s languages must allow programmers to add entirely new kinds of information to programs, and control how it is processed. This article argues that next-generation programming systems can accomplish this by combining three specific technologies.
Fuzzy Boundaries: Objects, Components, and Web Services:
It’s easy to transform objects into components and Web services, but how do we know which is right for the job?
If you are an object-oriented programmer, you will understand the code snippet, even if you are not familiar with the language (C#, not that it matters). You will not be surprised to learn that this program will print out the following line to the console: woof.
Garbage Collection as a Joint Venture:
A collaborative approach to reclaiming memory in heterogeneous software systems
Cross-component tracing is a way to solve the problem of reference cycles across component boundaries. This problem appears as soon as components can form arbitrary object graphs with nontrivial ownership across API boundaries. An incremental version of CCT is implemented in V8 and Blink, enabling effective and efficient reclamation of memory in a safe manner.
How Not to Write Fortran in Any Language:
There are characteristics of good coding that transcend all programming languages.
There’s no obfuscated Perl contest because it’s pointless.
Intermediate Representation:
The increasing significance of intermediate representations in compilers
Program compilation is a complicated process. A compiler is a software program that translates a high-level source language program into a form ready to execute on a computer. Early in the evolution of compilers, designers introduced IRs (intermediate representations, also commonly called intermediate languages) to manage the complexity of the compilation process. The use of an IR as the compiler’s internal representation of the program enables the compiler to be broken up into multiple phases and components, thus benefiting from modularity.
Java Security Architecture Revisited:
Hard technical problems and tough business challenges
This article looks back at a few of the hardest technical problems from a design and engineering perspective, as well as some tough business challenges for which research scientists are rarely trained. Li Gong offers a retrospective here culled from four previous occasions when he had the opportunity to dig into old notes and refresh his memory.
KV the Konqueror:
A koder with attitude, KV answers your questions. Miss Manners he ain’t.
Suppose I’m a customer of Sincere-and-Authentic’s (“Kode Vicious Battles On,” April 2005:15-17), and suppose the sysadmin at my ISP is an unscrupulous, albeit music-loving, geek. He figured out that I have an account with Sincere-and-Authentic. He put in a filter in the access router to log all packets belonging to a session between me and S&A. He would later mine the logs and retrieve the music—without paying for it.
Kode Vicious to the Rescue:
A koder with attitude, KV answers your questions. Miss Manners he ain’t.
Dear Kode Vicious, Where I work we use a mixture of C++ code, Python, and shell scripts in our product. I always have a hard time trying to figure out when it’s appropriate to use which for a certain job. Do you code in only assembler and C, or is this a problem for you as well?
Languages, Levels, Libraries, and Longevity:
New programming languages are born every day. Why do some succeed and some fail?
In 50 years, we’ve already seen numerous programming systems come and (mostly) go, although some have remained a long time and will probably do so for: decades? centuries? millennia? The questions about language designs, levels of abstraction, libraries, and resulting longevity are numerous. Why do new languages arise? Why is it sometimes easier to write new software than to adapt old software that works? How many different levels of languages make sense? Why do some languages last in the face of “better” ones?
Linguae Francae:
Is programming language a misnomer?
Many linguists are still busy trying to reconstruct the single ur-language presumed to have evolved over untold millennia into the thousands of human tongues - alive and dead, spoken and written - that have since been catalogued and analyzed. The amazing variety and complexity of known languages and dialects seems, at first parse, to gainsay such a singular seed.
META II: Digital Vellum in the Digital Scriptorium:
Revisiting Schorre’s 1962 compiler-compiler
Some people do living history -- reviving older skills and material culture by reenacting Waterloo or knapping flint knives. One pleasant rainy weekend in 2012, I set my sights a little more recently and settled in for a little meditative retro-computing, ca. 1962, following the ancient mode of transmission of knowledge: lecture and recitation -- or rather, grace of living in historical times, lecture (here, in the French sense, reading) and transcription (or even more specifically, grace of living post-Post, lecture and reimplementation).
OCaml for the Masses:
Why the next language you learn should be functional
Functional programming is an old idea with a distinguished history. Lisp, a functional language inspired by Alonzo Church’s lambda calculus, was one of the first programming languages developed at the dawn of the computing age. Statically typed functional languages such as OCaml and Haskell are newer, but their roots go deep.
Optimizations in C++ Compilers:
A practical journey
There’s a tradeoff to be made in giving the compiler more information: it can make compilation slower. Technologies such as link time optimization can give you the best of both worlds. Optimizations in compilers continue to improve, and upcoming improvements in indirect calls and virtual function dispatch might soon lead to even faster polymorphism.
Passing a Language through the Eye of a Needle:
How the embeddability of Lua impacted its design
Scripting languages are an important element in the current landscape of programming languages. A key feature of a scripting language is its ability to integrate with a system language. This integration takes two main forms: extending and embedding. In the first form, you extend the scripting language with libraries and functions written in the system language and write your main program in the scripting language. In the second form, you embed the scripting language in a host program (written in the system language) so that the host can run scripts and call functions defined in the scripts; the main program is the host program.
Postmortem Debugging in Dynamic Environments:
Modern dynamic languages lack tools for understanding software failures.
Despite the best efforts of software engineers to produce high-quality software, inevitably some bugs escape even the most rigorous testing process and are first encountered by end users. When this happens, such failures must be understood quickly, the underlying bugs fixed, and deployments patched to avoid another user (or the same one) running into the same problem again.
Purpose-Built Languages:
While often breaking the rules of traditional language design, the growing ecosystem of purpose-built "little" languages is an essential part of systems development.
In my college computer science lab, two eternal debates flourished during breaks from long nights of coding and debugging: "emacs versus vi?"; and "what is the best programming language?" Later, as I began my career in industry, I noticed that the debate over programming languages was also going on in the hallways of Silicon Valley campuses. It was the ’90s, and at Sun many of us were watching Java claim significant mindshare among developers, particularly those previously developing in C or C++.
Realtime Garbage Collection:
It’s now possible to develop realtime systems using Java.
Traditional computer science deals with the computation of correct results. Realtime systems interact with the physical world, so they have a second correctness criterion: they have to compute the correct result within a bounded amount of time. Simply building functionally correct software is hard enough. When timing is added to the requirements, the cost and complexity of building the software increase enormously.
Schizoid Classes:
Of class, type, and method
Smalltalk pays a high price elsewhere for taking object orientation to the extreme, notably in complete loss of static typing and serious runtime efficiency penalties. Special, one-instance forms of classes are, for many pro- gramming problems, not as good a conceptual match as modules. But at least it provides a single, consistent, and syntactically explicit call mechanism.
Sir, Please Step Away from the ASR-33!:
To move forward with programming languages we need to break free from the tyranny of ASCII.
One of the naughty details of my Varnish software is that the configuration is written in a domain-specific language that is converted into C source code, compiled into a shared library, and executed at hardware speed. That obviously makes me a programming language syntax designer, and just as obviously I have started to think more about how we express ourselves in these syntaxes.
Spicing Up Dart with Side Effects:
A set of extensions to the Dart programming language, designed to support asynchrony and generator functions
The Dart programming language has recently incorporated a set of extensions designed to support asynchrony and generator functions. Because Dart is a language for Web programming, latency is an important concern. To avoid blocking, developers must make methods asynchronous when computing their results requires nontrivial time. Generator functions ease the task of computing iterable sequences.
The Challenge of Cross-language Interoperability:
Interfacing between languages is increasingly important.
Interoperability between languages has been a problem since the second programming language was invented. Solutions have ranged from language-independent object models such as COM (Component Object Model) and CORBA (Common Object Request Broker Architecture) to VMs (virtual machines) designed to integrate languages, such as JVM (Java Virtual Machine) and CLR (Common Language Runtime). With software becoming ever more complex and hardware less homogeneous, the likelihood of a single language being the correct tool for an entire program is lower than ever. As modern compilers become more modular, there is potential for a new generation of interesting solutions.
The Curse of the Excluded Middle:
Mostly functional programming does not work.
There is a trend in the software industry to sell "mostly functional" programming as the silver bullet for solving problems developers face with concurrency, parallelism (manycore), and, of course, Big Data. Contemporary imperative languages could continue the ongoing trend, embrace closures, and try to limit mutation and other side effects. Unfortunately, just as "mostly secure" does not work, "mostly functional" does not work either. Instead, developers should seriously consider a completely fundamentalist option as well: embrace pure lazy functional programming with all effects explicitly surfaced in the type system using monads.
The Elephant in the Room:
It's time to get the POSIX elephant off our necks.
By writing code for the elephant that is Posix, we lose the chance to take advantage of modern hardware.
The Ideal HPC Programming Language:
Maybe it’s Fortran. Or maybe it just doesn’t matter.
The DARPA HPCS program sought a tenfold productivity improvement in trans-petaflop systems for HPC. This article describes programmability studies undertaken by Sun Microsystems in its HPCS participation. These studies were distinct from Sun’s ongoing development of a new HPC programming language (Fortress) and the company’s broader HPCS productivity studies, though there was certainly overlap with both activities.
There’s Still Some Life Left in Ada:
When it comes to survival of the fittest, Ada ain’t no dinosaur.
Ada remains the Rodney Dangerfield of computer programming languages, getting little respect despite a solid technical rationale for its existence. Originally pressed into service by the U.S. Department of Defense in the late 1970s, these days Ada is just considered a remnant of bloated military engineering practices.
Thou Shalt Not Depend on Me:
A look at JavaScript libraries in the wild
Most websites use JavaScript libraries, and many of them are known to be vulnerable. Understanding the scope of the problem, and the many unexpected ways that libraries are included, are only the first steps toward improving the situation. The goal here is that the information included in this article will help inform better tooling, development practices, and educational efforts for the community.
Toolkit: Java is Jumpin’:
There’s perception, and then there’s reality.
Even though the frenzied hype over Java has died down since the Internet bubble burst, Java is becoming hugely popular in the wireless space. Several events highlight its emergence. Most recently, in December, Texas Instruments opened a research operation in France to focus on the integration of Java apps into the next generation of wireless devices.
Two Books Alike in Dignity:
Formal and informal approaches to C++ mastery
Woke up this morning ... surprised to find my Sennheisers still connecting ears to my new MacBook Pro, with iTunes set to blues genre in shuffle mode. Lest you think I’ve succumbed to the despicable placement temptation that seduces so many columnists and filmmakers in these pursy times, I’m reluctant to price the named products, plug their sources, or elaborate on the immense pleasure I derive from their splendid cost-effective performances. Suffice it to mention that the subliminal album playing all night was Broke, Black and Blue, Volume 1, available for 7.95 US dollars or 7.95 Apple pounds sterling.
Understanding the Problem:
Is there any data showing that Java projects are any more or less successful than those using older languages?
I’ve done a one-day intro class and read a book on Java but never had to write any serious code in it. As an admin, however, I’ve been up close and personal with a number of Java server projects, which seem to share a number of problems.
Uninitialized Reads:
Understanding the proposed revisions to the C language
Most developers understand that reading uninitialized variables in C is a defect, but some do it anyway. What happens when you read uninitialized objects is unsettled in the current version of the C standard (C11).3 Various proposals have been made to resolve these issues in the planned C2X revision of the standard. Consequently, this is a good time to understand existing behaviors as well as proposed revisions to the standard to influence the evolution of the C language. Given that the behavior of uninitialized reads is unsettled in C11, prudence dictates eliminating uninitialized reads from your code.
Why LINQ Matters: Cloud Composability Guaranteed:
The benefits of composability are becoming clear in software engineering.
In this article we use LINQ (Language-integrated Query) as the guiding example of composability. LINQ is a specification of higher-order operators designed specifically to be composable. This specification is broadly applicable over anything that fits a loose definition of "collection," from objects in memory to asynchronous data streams to resources distributed in the cloud. With such a design, developers build up complexity by chaining together transforms and filters in various orders and by nesting the chains--that is, by building expression trees of operators.
Why Logical Clocks are Easy:
Sometimes all you need is the right language.
Any computing system can be described as executing sequences of actions, with an action being any relevant change in the state of the system. For example, reading a file to memory, modifying the contents of the file in memory, or writing the new contents to the file are relevant actions for a text editor. In a distributed system, actions execute in multiple locations; in this context, actions are often called events. Examples of events in distributed systems include sending or receiving messages, or changing some state in a node. Not all events are related, but some events can cause and influence how other, later events occur.