22 ms·
Felix - a fast scripting language
- nmcfarl 14y agoThis is interesting, but the home page is the most coherent and readable on the site. Better resources look to be: The Facebook group: http://www.facebook.com/groups/243958412369802/ http://www.facebook.com/groups/243958412369802/ And google group: https://groups.google.com/forum/?fromgroups#!forum/felix-language https://groups.google.com/forum/?fromgroups#!forum/felix-lan...
- srean 14y ago@nmcfarl thanks for resubmitting with a different url. I find the home page a bit baity but the tutorial page http://felix-lang.org/web/tutorial.fdoc http://felix-lang.org/web/tutorial.fdoc is great. Depending on how you look, it is C++ speed OCaML, or perhaps more correctly C++ in a fully type-inferred (unfortunately, nowadays almost everything gets called type-inferred. Hence the added qualification "fully"), ML like language. It does whole program optimization. It uses a mix of lazy and eager evaluation strategies for speed. I believe it can generate Python modules too, thanks to how well it interacts with C. The details have to be gleaned from the mailing list though.
- nmcfarl 14y agoI was actually using submissions as a poor man’s substitute for HN search :) I found the tutorial ( http://felix-lang.org/web/tutorial.fdoc http://felix-lang.org/web/tutorial.fdoc ) to be a bit info sparse when I had no clue what I was looking at. Once I’d poked a round a bit it was much better, and started answering questions I was having - mainly how FFI is handled: http://felix-lang.org/web/nutut/intro/intro_01.fdoc http://felix-lang.org/web/nutut/intro/intro_01.fdoc A very cool project.
- deleted 14y ago[deleted]
- asimjalis 14y agoOut of curiosity: How did you generate the slides?
- Yttrill 14y agoThe webserver, which is written in Felix, translates a particular format called "fdoc" to create the tutorial and slides, including embedded colourised hyperlinked Felix and C++ code. The translation is to a mix of HTML5 and Javascript. This link shows the source of the first slideshow: http://felix-lang.org/web/slides/language-overview.fdoc?text http://felix-lang.org/web/slides/language-overview.fdoc?text All the documentation and layout needs a lot more work. [BTW: I'm the primary developer]
- bdcravens 14y agoAll the documentation and layout needs a lot more work. Yes, clicking links to get a small page of content to only find another link to click .. gets old really fast. (Old as in it feels like the Java documentation circa 2001)
- cpeterso 14y agoYttrill, I see that Felix is 12+ years old. I remember reading about Felix on Lambda the Ultimate a few years ago. :) Over those 12 years, what are some of the biggest changes (in the language or its implementation) you have made? Where the changes mostly evolutionary? https://github.com/felix-lang/felix/commits/master?page=135 https://github.com/felix-lang/felix/commits/master?page=135
- Yttrill 14y agoThis is a hard question to answer. In general the emphasis changed from getting the compiler to work, and to generate efficient code, to using the technology to implement a rich set of libraries (feedback into compiler), and then writing some simple tools (feedback into libraries and compiler). Probably the single biggest feature was the introduction of Haskell style type classes as a way to systematically provide "generic" features like comparisons and conversions to string which are de rigueur in dynamically typed scripting languages. Less obvious but quite important was switching the parser from Ocamlyacc to Dypgen combined with OCScheme, which together put the grammar in user space, allowing almost the entire grammar to be put in the library. A lot of new features were added with very little or no change to the compiler by just adding some EBNF grammar and suitable Scheme action code to the parser. This can be very effective. For example, with only one extra term in the compiler, I added a dynamic object system that looks a lot like Java with objects and interfaces including "implements" and "extends" stuff. It just uses records of closures (the compiler mod added record extension), but the syntax is neat and almost immediately I used it to factor the webserver into separately compiled plugins. I originally implemented this as a kind of joke, to show off the expressive power in respect of Domain Specific Sub-Languages, but not intended for use. The joke was on me :)
- Toshio 14y agoLove at first sight, but the build script is broken. http://pastebin.com/raw.php?i=WzB5Jqyf http://pastebin.com/raw.php?i=WzB5Jqyf
- Yttrill 14y agoIt works with this: ~/felix>python3 Python 3.2.3 (v3.2.3:3d0686d90f55, Apr 10 2012, 11:25:50) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin and also on Linux with this: skaller@felix:~$ python3 Python 3.2.3 (default, Oct 19 2012, 20:10:41) [GCC 4.6.3] on linux2 I have been told that the script fails if you use a slightly different version of Python: File "/usr/lib/python3.3/subprocess.py", line 906, in communicate So it is an incompatibility in Python 3.3 subprocess module I think.
- Toshio 14y agoIndeed, I tried it on a fully up-to-date installation of ArchLinux.
- Yttrill 14y agoI am sorry about this problem. I have had a look and I understand what is happening but not how to fix it. Python 3.2 does not provide a timeout in the subprocess module. fbuild is using a module by Peter Astrand which derived a new class and adds a timeout. Unfortunately Python 3.3 adds the exact same argument to the API, but defaults it no None, which is clobbering the value used in the derived class somehow, leading to timeout of None being added to a floating point value.
- mrcharles 14y agoI'll stick with Lua. I wouldn't give up the dynamic aspects of a language like Lua just for a bit more speed. LuaJIT is more than enough, and if you are doing the hard number crunching that makes speed an issue there's a good chance it's not trivially harder just to write it in C++ to begin with.
- dkersten 14y agoFor raw number crunching, LuaJIT is plenty fast anyway (when you use the FFI to instantiate native types), so unless you need something real special (SSE perhaps), it may not even buy you that much to use C++ over LuaJIT.
- iskander 14y agoJust a small clarificatation: the 2.x version of LuaJIT only compiles floating point operations to SSE2 (http://lua-users.org/lists/lua-l/2010-03/msg00142.html http://lua-users.org/lists/lua-l/2010-03/msg00142.html). I'm not sure, however, whether it does vectorization or just operates on one float at a time.
- jheriko 14y agoSee fridgescript (http://code.google.com/p/fridgescript/ http://code.google.com/p/fridgescript/) - because you are going through C/C++ it is faster in its domain (x87 floating point work) if given good clean code. Its not big or clever - just that C/C++ kills its performance a little with restrictions like struct layout rules and standard library math functions being rubbish... (note the compiler uses almost no optimisation strategies and the language is very specific and almost useless though) That being said, I like the idea very much, I just object to the claim of fastest and the value the claim implies. Beating C is very easy if you know some very basic things about the restrictions placed on it by standards... :)
- PuerkitoBio 14y agoLooks very interesting, well done to whoever did this. After an admittedly quick and superficial glance at the tutorial, I'm not fan of chapter 6 though. Why so many ways to write calls? With no idiomatic syntax, it means I have to know all these variations if I hope to understand Felix code (since it is ok for anyone to choose whichever style).
- andrewflnr 14y agoI just don't understand why there are both gen and proc functions. Why have a separate kind of thing for functions that don't return anything?
- egonschiele 14y agoFunctions 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.
- andrewflnr 14y agoYeah, I got that, but gen's and proc's both have side effects. Why?
- Yttrill 14y agoBasically 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 :)
- andrewflnr 14y agoBut 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.
- raphinou 14y agoI've kept an eye on felix-lang the last several months, and the project seems to be progressing continuously. I'm curious though: has it been used in production? I'd be very interested in reading real use stories, with up and down sides! Also, how is the community doing, and what about contributors? Do both groups grow?
- zem 14y agoi've been keeping a vaguely interested eye on it for years, because it does look interesting. it has failed to make it to the front of my "learn this language next" priority queue due to the fact that i can't find anyone using it for anything, not even a hobby project on github. also, the documentation is a bit sparse. one killer feature that would make me start learning it immediately is good, well-documented qt bindings (i'm sure it is possible, since felix compiles down to c++, but with the sparse documentation i have no idea how i would go about getting it up and running, and insufficient motivation to first learn the language and then figure out how to do it).
- hipjiveguy 14y agohow does this compare with haXe (haxe.org)? I see that it's billed as a "C++ code generator" and as a "scripting engine".... Does it generate C++ code that I could use without Felix afterwards?
- Yttrill 14y agoYes, provided you collect all the required library headers and either sources or binaries: the generated C++ still requires run time libraries and the top level driver if it's a program. There is actually an option of flx, --bundle=dirname, which puts the generated C++ in a single directory, to make it simpler to ship the generated C++ to another platform. This does not do a full bundle, i.e. it doesn't package all the run time support code as well. That's on the TODO list, so you could literally copy the target directory to another machine and run "make" or something and only need a C++ compiler to build it. There's another aspect to your question: if by "use" you also mean "modify" then the current state is that Felix generated C++ is a bit hard to read. The code is "good enough" to add debugging prints but not much more. It would be good to improve this so the code is more readable.
- haberman 14y agoThe web page rubs me the wrong way. How can you claim to be the fastest anything without a single benchmark? How can you claim to be a "scripting language" when you're statically-typed and compile to C++? What does "scripting language" even mean then? How can you say things like "it will be a bit slow the first time but subsequent runs will load much faster than any VM." Any VM? Are you really "much faster" than: $ time lua empty.lua real 0m0.005s user 0m0.002s sys 0m0.002s $ time ./luajit empty.lua real 0m0.005s user 0m0.001s sys 0m0.002s Maybe there's cool stuff going on here but I can't get past being annoyed at these over-hyped claims.
- aaronblohowiak 14y agoMy "good enough" definition: a scripting language is a language that does not require you to write a main() function or define a class / object in order to produce output and features automatic memory management.
- chc 14y agoSo Common Lisp and Fortran are scripting languages? This test seems to be more like "Is the language heavily influenced by C or C++?"
- ciupicri 14y agoThen add it's easy to create one-liners.
- aaronblohowiak 14y agoI will add this as a great qualifier, though i fear the day where someone says that APL is a scripting language ;)
- ciupicri 14y agoI'm not familiar with APL, but after seeing the examples from Wikipedia [1], I think I know what you mean: # generates a typical set of Pick 6 lottery numbers x[⍋x←6?40] # finds all prime numbers from 1 to R (~R∊R∘.×R)/R←1↓⍳R # game of life life←{↑1 ⍵∨.∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵} [1] http://en.wikipedia.org/wiki/APL_%28programming_language%29#Examples http://en.wikipedia.org/wiki/APL_%28programming_language%29#...
- d0m 14y agoAt first glance, it seems fairly complex. For instance, 4 different kinds of variables, 3 different kinds of function. But I guess that's understandable if it compiles to C++ and is looking to be highly efficient.
- mitchi 14y agoWhich high level optimisations are we talking about?
- Yttrill 14y agoAs 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 sequence of straight line code with assignments can be converted into an expression by replacing occurrences of the variables with the initialising expressions. For a small number of uses, substitution is the usually the most efficient. For many uses, lifting the common expressions to a variable is more efficient. If we're dealing with a function (in C++ the model is a class) for which a closure is formed (in C++ the model is an object of the class) lazy evaluation is very expensive because the argument itself must be wrapped in an object to delay evaluation. By default, Felix val's and function arguments use indeterminate evaluation semantics, meaning the compiler gets to choose the strategy. This leads to high performance, but it also means we need a way to enforce a particular strategy: for example vars and var parameters always trigger eager evaluation. This leads to some complication in the language. Felix also does other optimisations, for example it does the usual self-tail call optimisation. This one works best if you do inlining at the right point to convert a non-self tail call (which cannot be represented for functions in C) into a self-tail call (which is replaced by a goto). Felix also does parallel assignment optimisation. It ensures type-classes have zero cost (unlike Haskell which, by supporting separate compilation, may have to pass dictionaries around). There is quite a lot more: eliminating useless variables, functions, unused arguments, etc. There are even user specified optimisations based on semantics, such as reduce idem[T] (x:list[T]) : list[T] = x.rev.rev => x; which says reversing a list twice leaves the original list, so just get rid of these two calls. Actually one important aspect to the optimisation process: by default a function is a C++ class with an apply() method. This allows forming a closure (object). The object is usually allocated on the heap. However Felix "knows" when it can get away with allocating such an object on the machine stack instead (saving a malloc and garbage collection). Furthermore, Felix "knows" when it can get away with a plain old C function, and generates one of those instead if it can. And all of that occurs only if the function wasn't entirely eliminated by inlining all the calls. So although you should think of Felix functions and procedures as objects of C++ classes allocated on the heap and garbage collected, any significant program implemented with this model without optimisations would just drop dead.
- TylerE 14y agoWhy do language designers continue to insist on semi-colon terminated lines?
- reinhardt 14y agoPerhaps to dissuade the lowest common denominator of programmers that get hung up on such superficial trivialities.
- TylerE 14y agoBut it's not triviality - it's noise - Signal: Good - Noise: Bad, got it? If you REALLY need end of line markers, any half-way competent text editor can display them for you.
- Kiro 14y agoYou obviously have no idea what signal-to-noise ratio is about if you think semicolons are noise. Who are you trying to impress?
- pekk 14y agoEnd of line is already encoded in source files as \n. Redundancy isn't noise, but it is redundant.
- seanmcdirmid 14y agoIf end of line always means end of statement, by all means get rid of semi colons. If some non-trivial algorithms is used to infer end-of-statement boundaries that is more complicated than detecting end-of-line, then...there will be subtle problems. I went through this transition before in Scala, the error messages got a lot worse after semi-colon inference was added. I wound up telling people to add semi-colons to their code when they were scratching their head at some sort of parse/type error message.
- andrewflnr 14y ago
- watmough 14y agoThey 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 language.
- asimjalis 14y agoWhat REPL do you use for Perl?
- Yttrill 14y agoThere 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 execution/editing with an environment that saves well defined symbols. Ultimately this would be tough to see through because Felix binds functions statically and lookup is setwise (like function scope in C) not linear, so recursive definitions cannot be introduced one at a time.
- rz2k 14y agoThis isn't very difficult to configure in Sublime Text 2 for different languages.
- andrewflnr 14y agoI like the array type syntax: an array of five ints is int*int*int*int*int === int^5 instead of something like int[5]. Lots of interesting little ideas.
- jaipilot747 14y agoHow is int*int*int*int*int or even int^5 better than a plain int[5]? To me, the use of mathematical operators * and ^ causes dissonance.
- munificent 14y agoIf you're coming from a type theory background (which, granted, few are), this operator is actually perfectly natural. http://en.wikipedia.org/wiki/Product_type http://en.wikipedia.org/wiki/Product_type
- lambdaphage 14y agoAren't product types just tuples, whereas arrays correspond to list types? The '^' operator can only construct arrays whose elements are of a single type, right?
- Yttrill 14y agoThat's correct. However, somewhat problematically, Felix considers the tuple int * int to actually be an array int ^ 2. It's not entirely clear this "automatically applied isomorphism" is a good idea though. However it means arrays "drop out" of the notion of a tuple as a special case. Internally such arrays have a special representation which allows arrays of 100,000 values, something which could never be represented by a tuple type (and still get reasonable compile times :)
- andrewflnr 14y agoI don't come from much of a type theory background. I certainly have no formal education in the field. I just know how a Cartesian product works, and that's enough to make me get it.
- michaelfeathers 14y agoWhile I enjoy reading about new and interesting languages (note: Felix has been around for over ten years), I really wish that language designers would put example code for something like FizzBuzz right on the front page to give people a flavor of the syntax. I can't remember how many times in my life I've done a link expedition through a website or docs just to see a simple programming example.
- Yttrill 14y agofor var i in 1 upto 15 do println$ match i % 3, i % 5 with | 0,0 => "Fizz-Buzz" | 0,_ => "Fizz" | _,0 => "Buzz" | _ => str i endmatch ; done Did I get the job?
- eriksank 14y agoI find it definitely a nice language proposal, but there are a few issues, I guess. A first one is that many of the distinctions introduced (such as proc,fun,gen) are all optimization issues. I would appreciate if it were possible to do that long after you're done with just making the program work. The language may force the developer way too early in the process to think of things that do not matter at that point. In the best case, it will matter later on, when the program truly works. Another issue I have is that the "simplifications" introduced initially lead to introducing lots and lots of additional symbols such $ and #, just because the simplification was apparently not leading to something simple. So, the language suffers from enforcing a premature optimization mindframe as well as from overly complex administrative simplification.
- Yttrill 14y agoThe proc/gen/fun distinction isn't entirely an optimisation issue, its a semantic one, heavily related to the implementation model. In principle fun and gen use the machine stack for return addresses whilst proc uses a heap allocated list which allows cooperative multi-tasking using channels for communication: such so-called spaghetti stacks are easy to swap. Machine stacks can only be swapped in a conforming way in C/C++ by using pre-emptive threads which is precisely what we're trying to avoid. I said "entirely" above because semantics and optimisation are heavily intertwined in any system. The comment about "syntactic sugar" is valid: there are at least four operators with different precedences all meaning "application of function to arguments". However note that in most languages this is true anyhow: x + y is really just add (x,y). Finding a good set of squiggles and marks that's acceptable to many people isn't easy. However the syntax is defined in the library, in user space, so you can add your own grammar or design your own domain specific sub-language, and add your favorite squiggles that way. Any contributions to making the standard syntax simpler would be welcome: I'm constantly struggling with this issue because I'm well aware syntax matters, especially early in learning a language.
- eriksank 14y agoI have created a blog post explaining why I think the language has too many problems to ever take off: http://erik-poupaert.blogspot.com/2013/01/the-felix-programming-language-or-how.html http://erik-poupaert.blogspot.com/2013/01/the-felix-programm...