Live data from Hacker News

Felix - a fast scripting language

felix-lang.org

81–88 of 88 posts

Re: Felix - a fast scripting language

#81

Earlier quoted context omitted.

> We're at least 20 years out from interpreters being meaningfully distinct from VMs and compiled languages. Compiled languages generally don't support eval. That's a pretty meaningful difference.

> Compiled languages generally don't support eval. Python is compiled to bytecode. It supports eval. So does Smalltalk. Lua would fall into this category as well, and a whole bunch of others. I don't think "compiled" means what you think it means anymore, which is my whole point.

> I don't think "compiled" means what you think it means anymore, which is my whole point.

See my other reply (http://news.ycombinator.com/item?id=5012218). "Compiled language" is an informal term that usually means "to machine code." If you take it to mean "compiles to any kind of IR at all," then basically all languages are compiled and the term is meaningless. But that's not how the term is generally used -- for example, see the Wikipedia article (http://en.wikipedia.org/wiki/Compiled_language).

There is a real difference between languages that can meaningfully be compiled directly to machine code and those that can only JIT-compile type-specialized traces/functions (with guards that fall back to the interpreter if the assumptions do not hold).

Re: Felix - a fast scripting language

#82
post #56

They are smoking crack if they think anyone will use a scripting language that doesn't have a functioning REPL. My goto-languages for quick development are Perl 5, Clojure and Javascript. All 3 are adequately fast for real tasks. All are cross-platform, and all 3 support a REPL that allows doing real work interactively. These conditions are the absolute minimum to be viable as a scripting or sketch/prototyping langua…

There is an alternative: a quick start GUI mini-IDE which allows you to type in and edit the code and press a button to run it. Such tools are mandatory on Windows anyhow: Ocaml and Python both have this for example. Most Unix editors like Vim or Emacs could be programmed to do this fairly easily I guess. I even wrote such a tool once using Tcl/Tk. I agree this is not the same as a REPL with line by line interactive…

This isn't very difficult to configure in Sublime Text 2 for different languages.

Re: Felix - a fast scripting language

#83

Earlier quoted context omitted.

> Compiled languages generally don't support eval. Python is compiled to bytecode. It supports eval. So does Smalltalk. Lua would fall into this category as well, and a whole bunch of others. I don't think "compiled" means what you think it means anymore, which is my whole point.

> I don't think "compiled" means what you think it means anymore, which is my whole point. See my other reply ( http://news.ycombinator.com/item?id=5012218 ). "Compiled language" is an informal term that usually means "to machine code." If you take it to mean "compiles to any kind of IR at all," then basically all languages are compiled and the term is meaningless. But that's not how the term is generally used -- for…

> If you take it to mean "compiles to any kind of IR at all," then basically all languages are compiled and the term is meaningless.

That's my point. It's a misnomer. It's the same thing as calling technology with the ability to parse context free grammars "regexes." It's a common usage that pollutes the precise meaning of technical terms. (And at the same time, generates misconceptions based on those technical terms.)

> There is a real difference between languages that can meaningfully be compiled directly to machine code and those that can only JIT-compile type-specialized traces/functions

Well, not so much as you'd think. In theory, the ability to do things like eval cuts off a lot of direct compilation to machine code, but in practice, we know this isn't necessarily true.

Re: Felix - a fast scripting language

#84
post #79
post #69

Earlier quoted context omitted.

As a whole program analyser, Felix does a lot of optimisations. The most important one is inlining. Felix pretty much inlines everything :) When a function is inlined, there are two things you can do with the arguments: assign them to variables representing the parameters (eager evaluation) or just replace the parameters in the code with the arguments (lazy evaluation). Substitution doesn't just apply to functions: a…

These are very good optimisations indeed. Inlining adds a lot more speed than people think. I don't understand why people want closures in their languages. You basically want a function that cheats her own scope... I don't get where the big deal is.

One needs closures, that is, functional values bound to some context, for higher order functions (HOFs). For example in C++ much of STL was pretty useless until C++11 added lambdas. Many systems provide for closures in C, by requiring you register callbacks as event handlers, and these callbacks invariably have an associated client data pointer. A C callback function together with a pointer to arbitrary client data object is a hand constructed closure.

The utility of closures derives from being able to split a data context into two pieces and program the two halves separately and independently. For example for many data structures you can write a visitor function which accepts a closure which is called with each visited value. Lets say we have N data structures.

Independently you can write different calculations on those values formed incrementally one value at a time, such as addition, or, multiplication. Lets say we have M operations.

With now you can perform N * M distinct calculations whilst only writing N + M functions. You have achieved this because both halves of the computation are functions: lambda abstraction reduces a quadratic problem to a linear one.

The downside of this is that the abstraction gets in the way of the compiler re-combining the visitor HOF and the calculation function to generate more efficient code.

There's another more serious structural problem though. The client of a HOF is a callback. In C, this is very lame because functions have no state. In more advanced languages they can have state. That's an improvement but it isn't good enough because it's still a callback, and callbacks are unusable for anything complex.

A callback is a slave. The HOF that calls it is a master. Even if the context of the slave is a finite state machine, where there is theory which tells you how to maintain the state, doing so is very hard. What you really want is for the calculation part of the problem to be a master, just like the HOF itself is. You want your calculation to read its data, and maintain state in the first instance on the stack.

Many people do not believe this and answer that they have no problems with callbacks, but these people are very ignorant. Just you try to write a simple program that is called with data from a file instead of reading the file. An operating system is just one big HOF that calls back into your program with stream data, but there's an important difference: both your program and the operating system are masters: your program reads the data, it isn't a function that accepts the data as an argument.

Another common example of master/master programming is client/server paradigm. This is usually implemented with two threads or processes and a communication link.

Felix special ability is high performance control inversion. It allows you to write threads which read data, and translates them into callbacks mechanically.

Some programming languages can do this in a limited context. For example Python has iterators and you can write functions that yield without losing their context, but this only works in the special case of a sequential visitor.

Felix can do this in general. It was actually designed to support monitoring half a million phone calls with threads that could perform complex calculations such as minimal cost routing. At the time no OS could come close to launching that number of pre-emptive threads yet Felix could do the job on a 1990's desktop PC (with a transaction rate around 500K/sec where a transaction was either a thread creation or sending a null message).

Re: Felix - a fast scripting language

#85

Earlier quoted context omitted.

Functions aren't supposed to have side effects and procs are. It makes sense since functions without side effects would allow for some nice compiler optimizations. The part that scares me is that the compiler doesn't enforce no side effects. This means you need to be extra careful when using someone else's code.

Yeah, I got that, but gen's and proc's both have side effects. Why?

Basically this is to support "expression" like syntax such as people are used to in C, for example i++ and x=y are expressions with side effects in C and a lot of C idioms depend on such things. This kind of thing was originally not allowed but I personally found it clumsy to manually split out the imperative parts from the functional parts, so I taught the compiler how to do it for me :)

Re: Felix - a fast scripting language

#86

Earlier quoted context omitted.

> I don't think "compiled" means what you think it means anymore, which is my whole point. See my other reply ( http://news.ycombinator.com/item?id=5012218 ). "Compiled language" is an informal term that usually means "to machine code." If you take it to mean "compiles to any kind of IR at all," then basically all languages are compiled and the term is meaningless. But that's not how the term is generally used -- for…

> If you take it to mean "compiles to any kind of IR at all," then basically all languages are compiled and the term is meaningless. That's my point. It's a misnomer . It's the same thing as calling technology with the ability to parse context free grammars "regexes." It's a common usage that pollutes the precise meaning of technical terms. (And at the same time, generates misconceptions based on those technical term…

> That's my point. It's a misnomer.

I disagree (as do the books sitting on my shelf), but I'm not really interested in debating this point of terminology.

> Well, not so much as you'd think.

No, really there is. Trying to deny this isn't insightful, it's myopic. Take the C function:

  int plus2(int x) { return x + 2; }
You can directly compile this into the following machine code, which needs no supporting runtime:

  lea    eax,[rdi+0x2]
  ret
Now take the equivalent function in Python:

  def plus2(x):
    return x + 2
Yes, it's true that this "compiles" (internally) to the following byte-code:

  3           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (2)
              6 BINARY_ADD          
              7 RETURN_VALUE
The question is: can you execute this byte-code without implementing an entire Python interpreter? The answer is no, because the BINARY_ADD opcode has to handle the case where "x" is an object that implements an overloaded operator __add__(). In this case, the user's __add__() method can be arbitrary Python code, and therefore requires an entire Python interpreter to fully and generally execute.

I expect you will want to talk about the limited circumstances where you can specialize this function ahead-of-time, thereby avoiding the fully-general implementation. This would again be missing the point. Python and C are different beasts, and this difference has far-reaching consequences on their implementations. Trying to draw an equivalence between all "compiled languages" does a disservice to people who are trying to understand the differences between them.

Re: Felix - a fast scripting language

#87
post #84
post #79

Earlier quoted context omitted.

These are very good optimisations indeed. Inlining adds a lot more speed than people think. I don't understand why people want closures in their languages. You basically want a function that cheats her own scope... I don't get where the big deal is.

One needs closures, that is, functional values bound to some context, for higher order functions (HOFs). For example in C++ much of STL was pretty useless until C++11 added lambdas. Many systems provide for closures in C, by requiring you register callbacks as event handlers, and these callbacks invariably have an associated client data pointer. A C callback function together with a pointer to arbitrary client data o…

I'm learning a lot thank you. Felix is pretty impressive!

Re: Felix - a fast scripting language

#88
post #85

Earlier quoted context omitted.

Yeah, I got that, but gen's and proc's both have side effects. Why?

Basically this is to support "expression" like syntax such as people are used to in C, for example i++ and x=y are expressions with side effects in C and a lot of C idioms depend on such things. This kind of thing was originally not allowed but I personally found it clumsy to manually split out the imperative parts from the functional parts, so I taught the compiler how to do it for me :)

But those expressions also return things. Why can't they be gen? Why would I use a proc instead? It seems like I must be missing something, but I can't see it.
Post reply on HN