Do they belong to you? Claim these comments.
Oliver Steele
Is this you? Claim Profile »
1 year ago
in What I didn’t get to on Languages of the real and artificial
@Raj, thanks for the kudos, and @Vijay, thanks for the link. I'll check out Lilly. (I also want to check out http://nodebox.net.)
@Danny: I tried the lztestkit URL (the link in the text, and copy/paste from your comment), and it worked for me. Maybe my web site was down for a moment? It seems to go out a lot these days.
I moved this to git and put it on http://gitorious.org/projects/lztestkit.
@Danny: I tried the lztestkit URL (the link in the text, and copy/paste from your comment), and it worked for me. Maybe my web site was down for a moment? It seems to go out a lot these days.
I moved this to git and put it on http://gitorious.org/projects/lztestkit.
1 year ago
in Supply/Demand Springs on Languages of the real and artificial
@Peter: Thanks! I wouldn't try to actually apply Hooke's law to this, though. I've updated the post to say that I don't think this is a "productive metaphor". If there is one I bet it has to do more with pressure than springs, but I haven't thought this through.
1 year ago
in What Every Programmer Needs to Know About Category Theory on Languages of the real and artificial
@nec, @Arjang: yes, nothing; sorry, it was intended as a joke, not a trick.
@Pseudonym: Congratulations on catching the subtleties in the title ("every programmer" versus "some programmers"; "needs" versus "should"). Nonetheless, I'm curious as to whether knowing category theory helps anyone program. The parts of category theory that relate to programming (functors, isomorphisms, monads and co-), I realized I was able to understand by using specific programming constructs as examples, and that knowing their categorial expressions didn't lead me to think about them any more deeply or to find analogies or solutions (the way that, say, realizing that you've implemented a state machine, or that your problem can be expressed in linear algebra, do).
And I haven't been able to apply the other parts of category theory to programming at all, although I've found them incredibly useful in doing, and teaching, math, and in thinking about other activities such as project management and other aspects of life. The Yoneda Lemma, for example, says that you aren't lost if you can find a landmark that you can get home from. (Think about it :-)
@Pseudonym: Congratulations on catching the subtleties in the title ("every programmer" versus "some programmers"; "needs" versus "should"). Nonetheless, I'm curious as to whether knowing category theory helps anyone program. The parts of category theory that relate to programming (functors, isomorphisms, monads and co-), I realized I was able to understand by using specific programming constructs as examples, and that knowing their categorial expressions didn't lead me to think about them any more deeply or to find analogies or solutions (the way that, say, realizing that you've implemented a state machine, or that your problem can be expressed in linear algebra, do).
And I haven't been able to apply the other parts of category theory to programming at all, although I've found them incredibly useful in doing, and teaching, math, and in thinking about other activities such as project management and other aspects of life. The Yoneda Lemma, for example, says that you aren't lost if you can find a landmark that you can get home from. (Think about it :-)
1 year ago
in Monads on the Cheap I: The Maybe Monad on Languages of the real and artificial
Hi, David! Good to hear from you again.
the_dormant: Okay, that does it. I'll finally at scala.
Alan, Thomas, thanks for the comments. Something that makes me uncomfortable about catching exceptions is that it has dynamic scope. If the accessors don't run any code, it's the same thing, but if product.offering is a getter that includes the expression record.connection, then the rescue will hide the case where record is null, as well as the case where product is null.
Alan: After I wrote this I found this post http://weblog.raganwald.com/2007/04/writing-pro... on Raganwald, which covered the "narrative mismatch" earlier and better. Braithwaite summarizes a post by Norbert Winklareth as being about "minimizing the semantic distance between the program as written and the solution to the problem as conceived by the programmer".
the_dormant: Okay, that does it. I'll finally at scala.
Alan, Thomas, thanks for the comments. Something that makes me uncomfortable about catching exceptions is that it has dynamic scope. If the accessors don't run any code, it's the same thing, but if product.offering is a getter that includes the expression record.connection, then the rescue will hide the case where record is null, as well as the case where product is null.
Alan: After I wrote this I found this post http://weblog.raganwald.com/2007/04/writing-pro... on Raganwald, which covered the "narrative mismatch" earlier and better. Braithwaite summarizes a post by Norbert Winklareth as being about "minimizing the semantic distance between the program as written and the solution to the problem as conceived by the programmer".
1 year ago
in Functional Javascript 1.0.2 on Languages of the real and artificial
Thanks, Anonymous. It was actually supposed to go to http://osteele.com/sources/javascript/functiona..., which packages up the two sources files and the example file. I've fixed it now.
1 year ago
in One-Line JavaScript Memoization on Languages of the real and artificial
Atany: thanks for the catch; 'tis done.
1 year ago
in Functional JavaScript on Languages of the real and artificial
Thomas, you're right; thanks for the find and the fix. I've fixed it above now.
I wrote the code that splices the output values into the "examples page":http://osteele.com/sources/javascript/functional exactly because I knew I wouldn't successfully keep them up to date with the expressions, but I couldn't (or didn't take the time to) do the same thing on this blog page :-(
I wrote the code that splices the output values into the "examples page":http://osteele.com/sources/javascript/functional exactly because I knew I wouldn't successfully keep them up to date with the expressions, but I couldn't (or didn't take the time to) do the same thing on this blog page :-(
3 years ago
in Inline JavaScript Console on Languages of the real and artificial
Tim: you're very welcome for the script, but I can't take any credit for the FF extension. It's by Joe Hewitt, and isn't related to this code.
3 years ago
in Inline JavaScript Console on Languages of the real and artificial
Johan: Yes, Firebug is *much* better, when you're using FireFox. (Except that I like my HTML element printing better :-). As of the latest Firebug, I just use this for Safari and IE.
Bernard: Do you have a pointer to either of these? I spent some time with Google but I didn't see anything I could stick in a web page.
Stephen: That's a great idea! (It turned out to be a little more complicated, because Firefox evaluates the SCRIPT targets asynchronously.) Try the following bookmarklet: (...I can't get the bookmarklet to show up in a WordPress comment, but you can view it in the header of http://osteele.com/sources/javascript/insert-co.... I'll add it to an HTML page later.)
Bernard: Do you have a pointer to either of these? I spent some time with Google but I didn't see anything I could stick in a web page.
Stephen: That's a great idea! (It turned out to be a little more complicated, because Firefox evaluates the SCRIPT targets asynchronously.) Try the following bookmarklet: (...I can't get the bookmarklet to show up in a WordPress comment, but you can view it in the header of http://osteele.com/sources/javascript/insert-co.... I'll add it to an HTML page later.)
3 years ago
in Javascript Beziers on Languages of the real and artificial
I just sped bezier.atT() up by 20%. It's now around 35ms on my MacBook (in power saving mode), in Firefox 1.5 and Safari 2.0.1. It was 45ms in Safari and 55ms in Firefox.
(Yahoo has an implementation to0, but it's around 150/300ms, or 110ms/460ms if you leave in the calls to parseInt.)
If you're calling bezier.atT() directly, the next optimization would be to inline that so that you can evaluated multiple points at once. That will save one function call per point.
If you're using the path interface, you could stub out the call to bezier.atT() to see if searching for the relevant segment is appreciable. That could use a binary search.
(Yahoo has an implementation to0, but it's around 150/300ms, or 110ms/460ms if you leave in the calls to parseInt.)
If you're calling bezier.atT() directly, the next optimization would be to inline that so that you can evaluated multiple points at once. That will save one function call per point.
If you're using the path interface, you could stub out the call to bezier.atT() to see if searching for the relevant segment is appreciable. That could use a binary search.
3 years ago
in Readable JavaScript Values on Languages of the real and artificial
Good question. In brief, JSON output is intended for consumption by computers and by libraries written in other languages, and Readable output is intended for humans. This has all sorts of repercussions such as whether RegExps, null, undefined, and NaN are represented; whether representations can be limited in length or depth, and so on. For a longer answer, see the bottom of the docs http://osteele.com/sources/javascript/docs/read..., where I've just added a list of differences.
3 years ago
in JSON for OpenLaszlo on Languages of the real and artificial
Oops! The correct link is http://osteele.com/sources/openlaszlo/json/open.... I think I've updated it everywhere...
3 years ago
in Visualizing Regular Expressions on Languages of the real and artificial
Thanks, alpheccar! You're exactly right about the disk animation. (Wordpress keeps cutting the end of my comment off. I'll answer this in a separate post.)
3 years ago
in Second grade squares on Languages of the real and artificial
Thanks, Bret. You're right about the labels on the arrows --- I've fixed them.
I've actually got a picture of the visualization you're suggesting here. When I started explaining squares to the seven-year-old this year, I almost printed that posting out, so that I could use it again. But we ended up going down a completely different path. That's one of the things I love about explaining things to people: even if I think I understand the material before-hand, I never end up taking the route I thought I would, when I'm traveling with someone else.
Nice web site, by the way!
I've actually got a picture of the visualization you're suggesting here. When I started explaining squares to the seven-year-old this year, I almost printed that posting out, so that I could use it again. But we ended up going down a completely different path. That's one of the things I love about explaining things to people: even if I think I understand the material before-hand, I never end up taking the route I thought I would, when I'm traveling with someone else.
Nice web site, by the way!
4 years ago
in Becoming Lisp on Languages of the real and artificial
Chris Dean and JJC: What sorts of things do you use macros for in Lisp?
I used to use macros for a several different things in Lisp. Many of them I switched to closures or multimethods for even when I still did most of my work in Lisp. Other uses of macros (for example, reader macros) rarely turned out to be worth the trouble of maintaining or integrating with other libraries.
The use of macros that I found the most powerful was to define new top-level defining forms, but metaprogramming works pretty well for this, and so does having a literal syntax for finite maps (or "dicts" or "hashes". I found Lisp's MAKE-HASHTABLE a poor substitute for this.
The other use of macros in my work was to define new binding forms such as with-open-file or with-graphics-context. Python doesn't have a good replacement for this.
JJC: "Just because Python has a lambda operator, it does /not/ mean it supports functional programming." What did you have in mind? (BTW, Python has had lambda for years. What it's added lately are Haskell-style list comprehensions, generators, and libraries such as itertools.)
I used to use macros for a several different things in Lisp. Many of them I switched to closures or multimethods for even when I still did most of my work in Lisp. Other uses of macros (for example, reader macros) rarely turned out to be worth the trouble of maintaining or integrating with other libraries.
The use of macros that I found the most powerful was to define new top-level defining forms, but metaprogramming works pretty well for this, and so does having a literal syntax for finite maps (or "dicts" or "hashes". I found Lisp's MAKE-HASHTABLE a poor substitute for this.
The other use of macros in my work was to define new binding forms such as with-open-file or with-graphics-context. Python doesn't have a good replacement for this.
JJC: "Just because Python has a lambda operator, it does /not/ mean it supports functional programming." What did you have in mind? (BTW, Python has had lambda for years. What it's added lately are Haskell-style list comprehensions, generators, and libraries such as itertools.)
4 years ago
in Becoming Lisp on Languages of the real and artificial
Brice: I think you've hit the nail on the head with your comment that different tools are appropriate for different teams (and for different projects, and different contexts --- I wouldn't have written a rendering engine in Python, or PyWordnet in assembly).
Still, it would be nice if the different tools for different teams could be hosted in one language.
If you start with a superset of the features you need, subsetting it requires policies, conventions, and, ideally, tool support --- something like Checkstyle or Macker that can be run as a supplement to the compiler to create a composite compiler that compiles a subset of the full language, or like the language devels in DrScheme.
If you start with a subset of the features you need, you end up writing what would have been the compiler expansion of these features into your source code, using a precompiler, or implementing these features with metaobject programming. But you can only do the last if the language has metaobject programming features to begin with, which reduces this problem to the previous case, where you want the language to have these features, but you want to restrict their use, or the use of the features they create, to certain libraries. Something like Macker for language features seems like it would be appropriate here.
Still, it would be nice if the different tools for different teams could be hosted in one language.
If you start with a superset of the features you need, subsetting it requires policies, conventions, and, ideally, tool support --- something like Checkstyle or Macker that can be run as a supplement to the compiler to create a composite compiler that compiles a subset of the full language, or like the language devels in DrScheme.
If you start with a subset of the features you need, you end up writing what would have been the compiler expansion of these features into your source code, using a precompiler, or implementing these features with metaobject programming. But you can only do the last if the language has metaobject programming features to begin with, which reduces this problem to the previous case, where you want the language to have these features, but you want to restrict their use, or the use of the features they create, to certain libraries. Something like Macker for language features seems like it would be appropriate here.
4 years ago
in Becoming Lisp on Languages of the real and artificial
Hi, Brice, and thanks!
Your comment was very interesting, and raised a lot of issues --- especially the difference between readability and writability, and the difference (which you hint at) between features and paradigms. Those are worthy of a longer answer; I'm not going to try at all in this comment.
Two points:
1. Features increase the range of readability. Each feature makes it possible to write both more-readable and less-readable programs than one could write without it. Consider Python
Consider virtual functions (or method overriding, in an OO language). Virtual functions make it easier to write readable programs, because they move the switch statements or function pointers that would otherwise be necessary out of the problem domain code. (In fact, virtual functions are a way of moving this dispatch code out of the program source entirely, to the language implementation). But virtual functions also make it easier to write unreadable programs --- it can be very hard to find which implementation of a method is called under which circumstances.
I'd rather have the possibility of working with readable programs than the certainty of avoiding unreadable programs, but it depends on who you're working with and where the code you read is coming from.
2. "source code from different projects doesn't seem like it's written in the same language": Maybe this is a good thing! Consider the case where the best language for one project is Prolog and the best language for another project is Haskell. Then there's two choices: Use completely different languages for different projects, or using the wrong language for some projects because it's the right language for others. Language features give you a third choice: use different libraries and extensions for different projects. It's not clear that seeming like different projects are in different languages is as bad as the alternatives: being in different languages, or being in the wrong language!
Your comment was very interesting, and raised a lot of issues --- especially the difference between readability and writability, and the difference (which you hint at) between features and paradigms. Those are worthy of a longer answer; I'm not going to try at all in this comment.
Two points:
1. Features increase the range of readability. Each feature makes it possible to write both more-readable and less-readable programs than one could write without it. Consider Python
_&2d;new__. A program with __new__ strewn throughout is less readable than it otherwise would be. A program that uses a named tuple class (which can be implemented with a single __new__) can be more readable than one that doesn't --- especially if the one that doesn't uses what is basically a source-level expansion of the named tuple implementation, each place a named tuple would be appropriate.Consider virtual functions (or method overriding, in an OO language). Virtual functions make it easier to write readable programs, because they move the switch statements or function pointers that would otherwise be necessary out of the problem domain code. (In fact, virtual functions are a way of moving this dispatch code out of the program source entirely, to the language implementation). But virtual functions also make it easier to write unreadable programs --- it can be very hard to find which implementation of a method is called under which circumstances.
I'd rather have the possibility of working with readable programs than the certainty of avoiding unreadable programs, but it depends on who you're working with and where the code you read is coming from.
2. "source code from different projects doesn't seem like it's written in the same language": Maybe this is a good thing! Consider the case where the best language for one project is Prolog and the best language for another project is Haskell. Then there's two choices: Use completely different languages for different projects, or using the wrong language for some projects because it's the right language for others. Language features give you a third choice: use different libraries and extensions for different projects. It's not clear that seeming like different projects are in different languages is as bad as the alternatives: being in different languages, or being in the wrong language!
5 years ago
in Test versus Type on Languages of the real and artificial
Peter writes: "Implicitly typed language people don't have experience with a tool like IntelliJ IDEA whre the 'coding/refactoring' process is actualy driven by types which makes it even faster then without writing types at all. Tools like IDEA are not possible without explicit typing." Actually, the first refactoring browser was for Smalltalk, an ITL. (See here, here, and here). This obviously doesn't depend on types.
But the general point, that IDEs can use type information to provide additional services, such as parameter lists and method name completion, is an excellent one.
The other two uses of types that I didn't touch on is their use as program documentation, and to improve runtime performance.
The general point is that the fact that a runtime for a dynamically typed language can do "poor man's type inference" doesn't help the other readers of the program source: development tools, and humans.
I wrote about one problem with using manifest types for these purposes is their maintenance costs. That's just a cost/benefit tradeoff, and when you change the tools, the performance requirements, or how much of the design of the program is expressed through the types of its variables, the tradeoff can change.
But the general point, that IDEs can use type information to provide additional services, such as parameter lists and method name completion, is an excellent one.
The other two uses of types that I didn't touch on is their use as program documentation, and to improve runtime performance.
The general point is that the fact that a runtime for a dynamically typed language can do "poor man's type inference" doesn't help the other readers of the program source: development tools, and humans.
I wrote about one problem with using manifest types for these purposes is their maintenance costs. That's just a cost/benefit tradeoff, and when you change the tools, the performance requirements, or how much of the design of the program is expressed through the types of its variables, the tradeoff can change.
5 years ago
in Test versus Type on Languages of the real and artificial
Dave writes: "The fact is that without static typing you HAVE to write tests to make sure you aren't mis-using variables IN ADDITION to the normal tests you would write to test functionality." But if your functional tests don't test for correct usage of these variables, you've either got some unused variables in your source or you aren't testing much of your program's functionality. And most ways of mis-using a variable don't have to do with treating it as the wrong type.
Dave also suggests writing two programs in Python, one with and one without type definitions. I haven't run this exact experiment, but I did write both a Java and a Python interface to Wordnet, and tools that used each of these. The difference was striking. You can chalk some of this up to other differences between Java and Python, but I've done enough programming in languages that vary from each other in different ways (C++, Haskell, Common Lisp, and Smalltalk, to pick three that are very different from each other) to have something of a feel for what slows me down in each of them.
Dave also suggests writing two programs in Python, one with and one without type definitions. I haven't run this exact experiment, but I did write both a Java and a Python interface to Wordnet, and tools that used each of these. The difference was striking. You can chalk some of this up to other differences between Java and Python, but I've done enough programming in languages that vary from each other in different ways (C++, Haskell, Common Lisp, and Smalltalk, to pick three that are very different from each other) to have something of a feel for what slows me down in each of them.