7 ms·
In those times I wish I could use the emacs lisp way: (let (dir "/foo") (create-directory dir) (with-current-directory dir (delete-all-
by swah 12y ago
In those times I wish I could use the emacs lisp way:
(let (dir "/foo")
(create-directory dir)
(with-current-directory dir
(delete-all-files-recursively)))
Factor recognized the value of dynamically scoped variables: http://concatenative.org/wiki/view/Factor/FAQ/What's%20Factor%20like%3F http://concatenative.org/wiki/view/Factor/FAQ/What's%20Facto...
A lot of code became much simpler because of that decision.
- Alupis 12y agoThis isn't really fork() failing per se -- but rather a failed program/script that did not understand the well defined and clearly documented behavior of fork().
- dllthomas 12y agoThe man page says, "On failure, -1 is returned in the parent, no process is created, and errno is set appropriately." So if fork is behaving as documented, returning -1 is because of "fork failing".
- Alupis 12y agoTrue -- I guess fork() has failed at that point. I was more getting at the article's authors scenarios of careless scripts treating -1 as a valid pid (which should always be > 0), which would be a failure of the script instead.
- dllthomas 12y agoWell, it's a failure of the script and the POSIX API - it is unfortunate that a pid_t inhabited by -1 means "failure" in one case and "everything" in another. It is certainly not fork, narrowly, to blame.
- M00n_Sl47r 12y agoI think the point that the author was making, outside of any criticism to the API itself, is that the hapless programmer may not know that fork() could even return -1. The article is pointing out that possibility as documented by the API, not criticizing a failure of the API. Whether or not the API is faulty in this--and I tend to agree with you--is outside of the scope of the article, though only just.
- dllthomas 12y agoI wasn't making any particular comment on the content of the article. It was certainly relevant to the discussion tangent the thread had wandered down.
- brazzy 12y agoPsst - it's "per se"...
- Alupis 12y ago;-P
- bostonpete 12y ago¿Por qué?
- Alupis 12y agoI originally had "per-say" instead of the correct "per se"
- yosefk 12y agoTaking the square root of a negative number removing all the files in your home directory could be "well defined and clearly documented behavior". Would you blame the API author at that point or would it still be strictly your fault? At what point do API authors share the blame for a needlessly harsh punishment delivered upon a predictably common error? I certainly prefer to work with systems produced by people tending to think it'd be their fault more often than not.
- Alupis 12y agoI could argue, however, that in this particular case, it's the user's fault for failing to understand the full and defined behavior of fork() in addition to failing to understand the full and defined behavior of other functions, ...say, kill(). It's just as wrong to feed kill() -1 as it would be to feed it -48585 or "babdkd" (unless that is explicitly your intention). A simple sanity check of if [ "${pid} > "0" ]; is all that's necessary to protect against this behavior. So, I would argue, the fault lays on the users, not the creator, for not understanding the API when all materials necessary to understand said API are freely available. (with that said, I think it's safe to say, we've all been bitten by not fully understanding some function before)
- ajkjk 12y agoThere'd be far fewer bugs if everyone knew exactly how everything else works. This kind of mistake is godawful and should not be defended. (but it's correctly fixed through stronger typing, not through choosing -48585 as the code for killing everything).
- Alupis 12y ago> not through choosing -48585 as the code for killing everything) Actually, only -1 is the code that "kills everything" > There'd be far fewer bugs if everyone knew exactly how everything else works. Perhaps I misinterpreted your meaning, because you seem to be advocating using programming and scripting languages without actually bothering to learn them. Of course this can, will and does lead to very bad effects. The bottom line is, if you are going to use a function in your program/script -- please, read the docs and understand what is will return at the very least.
- staunch 12y ago$ mkdir /tmp/foo && cd /tmp/foo && touch bar.txt
- davvid 12y agoYes. Always chain sequential commands with &&. Always. This style is pretty prevalent when writing test cases in shell (or just shell scripts in general), e.g. when using something like sharness[1]. [1] https://github.com/mlafeldt/sharness https://github.com/mlafeldt/sharness
- stingraycharles 12y agoWhen writing test cases in shell, you generally just implement a die() function and execute all commands `foo || die "bar"`
- nitrogen 12y agoIf you don't need to specify a custom message, you could also use "set -e" to die automatically on command failure and use "trap ... EXIT" to display some kind of failure message.
- pimlottc 12y ago"bash -e" has much the same effect: it basically exits on the first failed command, with considerations for pipelines, conditionals and the like. http://www.gnu.org/software/bash/manual/bashref.html#index-set http://www.gnu.org/software/bash/manual/bashref.html#index-s...
- pflanze 12y agoNote this recent discussion about bash -e, including my post that "the disappointment with set -e is that it does not work everywhere". https://news.ycombinator.com/item?id=8054440 https://news.ycombinator.com/item?id=8054440
- 12y ago
- tedunangst 12y agoWhat's wrong with the C version? char *dir = "/foo"; mkdir(dir, 0700); if (chdir(dir) == 0) delete_all_files();
- swah 12y agoNothing, of course. I just find the macros that give you a "modified environment" to run some code short and sweet. with-temp-buffer is another example: a macro that bridges the functions for "string manipulation" and the ones for "buffer manipulation", since you start writing stuff this way: (defun replace-in-string (str from to) (with-temp-buffer (insert str) (beginning-of-file) ;;; Here you can use all your normal text editing commands (replace-regexp from to nil t) (buffer-string))) Lots of dirty manipulation, but from outside its a pure function, and doesn't change the editor state in any way after it runs.
- qewrffewqwfqew 12y agoThat's incomplete in that it doesn't automatically chdir back. A proper block-scope "with-" macro will wrap the body in something like: char *olddir = getcwd(); chdir(newdir); try { do_stuff(); } finally { chdir(olddir); }
- jacquesm 12y ago'try' and 'finally' are in C now? Someone should warn the GCC guys they're behind the times. Also, getcwd has a size parameter these days, and of course you want to check if the getcwd actually worked.
- xxs 12y agoThe OP said: wrap in a macro having similar properties (ala pseudo code).
- jacquesm 12y agoGood luck writing a macro in C to express language functionality for which you don't have the primitives. It's not exactly lisp. Think of C macros as a way to save you some typing and lisp macros as a way to extend the language.
- hollerith 12y agoI fail to see how dynamic scope pertains to the code you wrote or helps avoid the bug described in grandparent. Specifically, the code you wrote would behave the same if `dir` had lexical scope.
- mst 12y agoThe with-current-directory part is the dynamic part - i.e. within its dynamic scope, the current directory is now dir. The scoping of the dir variable itself is irrelevant.
- hollerith 12y ago`with-current-directory` has to be a macro because if it is not, then the evaluation of (delete-all-files-recursively) happens before the definition of with-current-directory can change the current directory. What the person meant when he wrote, "In those times I wish I could use the emacs lisp way," is, "In those times I wish I could use a lisp _macro_" -- particularly, one of those macros that makes a change, runs some code ("the body") then undoes the change. Since all lisps have macros, the code above would work in any lisp -- not just Emacs Lisp. Among lisps, Emacs Lisp is famous for its dynamically scoped variables. Consequently, the specific reference to Emacs Lisp perpetuates the confusion that how variables are scoped has anything to do with what we have been talking about.
- swah 12y agoYes, but emacs lisp is the only lisp I used, and lives in an environment where those macros are really useful. with-auto-compression-mode with-case-table with-category-table with-coding-priority with-current-buffer with-decoded-time-value with-demoted-errors with-electric-help with-help-window with-local-quit with-no-warnings with-output-to-string with-output-to-temp-buffer with-selected-frame with-selected-window with-silent-modifications with-syntax-table with-temp-buffer with-temp-buffer-window with-temp-file with-temp-message with-timeout with-timeout-suspend with-timeout-unsuspend with-wrapper-hook