Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> opposite to the Unix philosophy

Bash:

  $ foo()
  {
    bar ()
    {
      echo I am bar
    }
  }
  $ bar
  bar: not found
  $ foo
  $ bar
  I am bar
Pretty much the same thing as the Ruby example.

This is simply because function defining is a kind of statement or expression with a side effect which must be evaluated. The side effect is global (a name is globally associated with a function). So if the side effect is in a function body, its evaluation is delayed until the function is called, and then its effect is still global.



If you're a sufficiently advanced Unix purist (aka a Plan 9 user), the Bourne shell is a violation of Unix principles. Contrast the v6 shell, where this construct is impossible because there are no functions. Now that's do-one-thing-do-it-not-quite-terribly.

Does this work in Plan 9 rc?


This is indeed the basic feature of any language that's evaluated at runtime. When working with such a language, one needs to learn the program as a dynamically growing construct instead of a vision cast in stone when you press the "compile" button.


Or rather, one needs to learn which constructs destructively manipulate a global environment, and which perform lexical binding.

In Python, an inner def will lexically bind a function, creating a closure. Python is not less dynamic than Ruby.

In Common Lisp, a defun inside a defun will behave similarly to Ruby; but if you want lexically scoped local functions, you use a different operator, namely flet or labels.

Scheme has a define which is lexical: it brings a lexical identifier into the scope for forms which follow.

Lexically scoped items, even in a dynamic language, in fact can be "cast in stone when you press the compile button"; they are cast in that stone which is the entire compiled environment of the surrounding function.


Touché




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: