HNHacker News
TopNewBestAskShowJobs

juki

285 karma · joined January 14, 2017

submissionscomments
juki··on Write dumb code
I think you misread that. They said "comparable to" (equally sane), not "compared to".
juki··on GNU Readline for Better Productivity on the Command Line
Also when you just want to run a single command, `M-&` (`async-shell-command`) is always handy. Or in Dired mode `&` for operating on files. At least for me those two work for majority of shell usage.
juki··on Ask HN: Learning Lisp, and I have some questions
In that situation you could simply represent `null` as a keyword :NULL, `false` as NIL and `[]` as a vector (or some other non-list datastructure).
juki··on Ask HN: Learning Lisp, and I have some questions
Most of the time there just isn't any need to make a difference between the three. There are basically just two common situations where you need to be able to tell the difference:

1. Telling apart optional arguments to a function that weren't given from arguments that were given and were NIL. Typically giving a default value for the argument is sufficient to avoid the problem, but you can also add an extra parameter that tells whether the argument was given.

    (defun foo (&optional (x :default-value xp))
      ;; X holds the argument given by the caller, or the keyword
      ;; :DEFAULT-VALUE if nothing was given.
      ;; XP is T if the argument was given, or NIL if it was not given.
      )
2. Finding an item that may be NIL. Functions such as GETHASH (which looks up a key in a hash table) usually allow you to specify a default value, and they will return a second value to indicate whether something was found.

    ;; Increment the value of KEY in TABLE, or if the key doesn't 
    ;; exist, use 10 as a default, increment that and set the 
    ;; result to the table.
    (incf (gethash key table 10))

    (multiple-value-bind (value existsp) (gethash key table)
      ;; VALUE holds the value if it exists, or NIL if it doesn't.
      ;; EXISTSP is T if the key exists, or NIL if it doesn't.
      )
Notice that in CL additional return values can be ignored if you're not interested in them, so you only need to use MULTIPLE-VALUE-BIND when you actually need it. You could also wrap it in a trivial macro if you're using it a lot.

    (defmacro if-some-let ((var form) &body (then &optional else))
      (let ((somep (gensym "SOMEP")))
        `(multiple-value-bind (,var ,somep) ,form
           (if ,somep ,then ,else))))
    
    (if-some-let (val (gethash key table))
      (format t "Found: ~a~%" val)
      (format t "Didn't find.~%"))
juki··on Ren: a lightweight data-exchange text format
> ¤ is generic, but not on any keyboard layout I know of.

Finnish (/ Swedish) keyboards have ¤ on `<Shift> 4` ($ is `<Alt Gr> 4`).

juki··on Block Comments Are a Bad Idea
> LISP/Scheme, where block comments were never a thing (I think.)

Lisp does have block comments,

    #| This is a block comment |#
You can also use feature expressions to effectively comment out code

    #+(or)
    (defun foo ...)
The reader will skip over the following sexp if the feature expression isn't true (and `(or)` never is).
juki··on New theory why languages don’t all have the same number of terms for colors
> There are no words for this slush-like substance that falls from the sky, sometimes as small clumps but other times in clumps large enough that you can hear them hit the ground.

That sounds like what we call "räntä" in Finland, which, according to Wikipedia, is called "sleet" in Commonwealth countries.

[1]: https://en.wikipedia.org/wiki/Rain_and_snow_mixed#Terminolog...

juki··on Org-Mode Is One of the Most Reasonable Markup Languages to Use for Text
`#+...` is called "affiliated keyword" in the spec[1]. Those are distinct from comments, which are required to have a whitespace character after the hash sign[2].

[1]: http://orgmode.org/worg/dev/org-syntax.html#Affiliated_keywo...

[2]: http://orgmode.org/worg/dev/org-syntax.html#Comments

juki··on Org-Mode Is One of the Most Reasonable Markup Languages to Use for Text
I assume whoever made the decision figured that minus-sign is more commonly used for other purposes in text (although usually one should be using an en/em dash (which would be `--`/`---` in Org-mode) instead), so it would be harder to read (especially in text-mode where you don't see the strikethrough).
juki··on Org-Mode Is One of the Most Reasonable Markup Languages to Use for Text
No, it wouldn't. The end plus-sign must be at the end of the word.
juki··on Org-Mode Is One of the Most Reasonable Markup Languages to Use for Text
> Would put a strikethrough all the advantages above because they use the + symbol.

No, it wouldn't. `+` is a valid list bullet in Org-mode. For strikethrough, the plus-signs must be attached to the start and end of the words (`+an example+`).

juki··on Org-Mode Is One of the Most Reasonable Markup Languages to Use for Text
`C-c C-l` is also useful if you're linking to files (org or other). You can use `M-x org-store-link` in the link destination, and a subsequent `C-c C-l` will let you add that link easily.
juki··on Org-Mode Is One of the Most Reasonable Markup Languages to Use for Text
You can use `C-c '` to edit the block in a new buffer without colons or indentation at the start.
juki··on What makes a good REPL?
SLIME does let you redefine functions and restart a stack frame (assuming the Lisp implementation supports that). You can even do it without using Emacs/SLIME, although that's not very convenient of course. A silly example with SBCL,

    ~ $ rlwrap sbcl --noinform
    CL-USER> (defun foobar (x y)
               (if (evenp x)
                   (/ x y)
                   (* x y)))
    
    FOOBAR
    CL-USER> (foobar 10 0)
    
    debugger invoked on a DIVISION-BY-ZERO in thread
    #<THREAD "main thread" RUNNING {1001BB64C3}>:
      arithmetic error DIVISION-BY-ZERO signalled
    Operation was /, operands (10 0).
    
    Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
    
    restarts (invokable by number or by possibly-abbreviated name):
      0: [ABORT] Exit debugger, returning to top level.
    
    (SB-KERNEL::INTEGER-/-INTEGER 10 0)
    0] backtrace 3
    
    Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1001BB64C3}>
    0: (SB-KERNEL::INTEGER-/-INTEGER 10 0)
    1: (FOOBAR 10 0)
    2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (FOOBAR 10 0) #<NULL-LEXENV>)
    
    0] down
    (FOOBAR 10 0)
    
    1] source 1
    
    (IF (EVENP X)
        (#:***HERE*** (/ X Y))
        (* X Y)) 
    1] (defun foobar (x y)
         (if (and (evenp x) (not (zerop y)))
             (/ x y)
             (* x y)))
    
    WARNING: redefining COMMON-LISP-USER::FOOBAR in DEFUN
    FOOBAR
    1] restart-frame
    
    0
juki··on Why I haven't jumped ship from Common Lisp to Racket just yet
You can use CL for #!-scripts too. SBCL has a `--script` option for running scripts. You'll probably want to create a core with whatever libraries you need for scrips, so that the start-up time will be fast. The core will be big, but it can be shared for all scripts, so that's not much of a problem.
juki··on Why Type Systems Matter
Common Lisp does allow one to declare types in order to have the compiler optimize the code. SBCL[0] in particular is known to be pretty good at that. Macsyma also lives on in Common Lisp as Maxima[1].

[0]: http://sbcl.org/ [1]: http://maxima.sourceforge.net/

juki··on Percentage of Europeans Who Are Willing to Fight a War for Their Country
Of course one should remember that Finland lost WW2 "better" than most countries won it. In fact, many Finns will say that it was a victory. While the war was brutal, Finland is one of the few countries where the casualities were mostly limited to the military. There were only ~2000 civilian deaths. Finland was never occupied[1] and there was no large scale bombing of cities. Finland remained an independent democracy, and prospered after the war. The contrast to the rest of Eastern Europe is pretty stark.

[1]: Only one major Finnish city (Viipuri) was occupied by the USSR (after the civilian population of the city was evacuated).

juki··on CHIP-8 in Common Lisp
Common lisp has this universal setter-macro, SETF, which can be used to set values to all sorts of places.

In this case you would use

    (setf (vref chip x y) new-value)
to call the function (just like with AREF above). Using SETF has the advantage that you can define "modify macros" that read and write a place. For example,

    (incf (vref chip x y) delta)
would increment the place by DELTA. Or

    (rotatef (vref chip x1 y1)
             (vref chip x2 y2))
would swap two pixels.
juki··on Languages Which Almost Became CSS
There is also LASS[1] for Common Lisp. You use it either as a library for generating CSS, or as a standalone preprocessor.

[1]: https://github.com/Shinmera/LASS

juki··on Common Lisp Runtime Redefinition (2002)
Lisp doesn't really have separate release/debug modes[1]. When you want to distribute a program as a binary, you dump the image and set a custom top-level function to use instead of the default REPL. The program will still contain the compiler/interpreter and can redefine everything just like during development (altough the program might not use or expose those features to the user). The REPL isn't in any way magical in Lisp; it's just the default option for interacting with the Lisp.

[1]: You can ask the Lisp to drop all debug information as an optimization, which makes development impractical, but still possible. Some implementation might allow you to distribute a program without the compiler, but the standard does not specify that.

juki··on Antisocial Coding: My Year at GitHub
> are you sure you're not yourself requiring me to adopt to your communication modalities?

They are. That's the whole point. If someone comes to try and convince you of their point, you can either listen and engage in a discussion, or if you believe that isn't going to work out, you can refuse. Both are valid options and necessary at times.

Likewise if you want to convince someone of your point and they refuse to listen to you, you can either change your approach so that they do, or declare them a lost cause and move on. Both are again valid options and necessary at times.

The problem is when you keep trying the approach that the other person doesn't want to listen to. That will just alienate them further, and can easily turn into harassment.

juki··on Oculus founder Palmer Luckey is developing border surveillance technology
Do notice that the article doesn't claim they found any evidence of active development or use WMDs, which is what the USA claimed as a justification for the invasion. All they found were abandoned chemical weapons from the 80s. Everyone already knew that Iraq used chemical weapons back then, so the only new discovery was that the remaining weapons had just been abandoned instead of properly destroyed.
juki··on Simplified Common Lisp reference
I assume you're thinking about Schemes `(let loop (...) ...)`, but that doesn't exist in Common Lisp. CL:LOOP is a looping macro with its own small DSL.

    (loop :for i :below 5
          :when (evenp i) :collect i)
    ;=> (0 2 4)
juki··on Ask HN: Do you still use browser bookmarks?
I use Emacs / Org Mode for bookmarks. I use a few different browser profiles, and usually always want to open a bookmark in a specific profile. Having all bookmarks in one place is much easier than figuring out which browser I need and then finding the bookmark in it. Plus this way I can use other Org Mode features with them too (adding any arbitrary notes/tasks to them, todo keywords for a reading list, refiling/archiving, etc.)

Basically I just add the properties URL and BROWSER to any entry I want to be a bookmark. I have the numpad key 4 bound to a command that opens the url (works either in the org file buffer itself, or from an agenda view). I also have the numpad key 1 bound to an agenda search for the tag :bm: (searching for a property is too slow), so I can easily get a list of all bookmarks, which can then be filtered by tags, category, top-level headline and regexes.

juki··on How to write Common Lisp in 2017 – an initiation manual
SBCL actually does have an interpreter, but doesn't use it by default. You can set

    sb-ext:*evaluator-mode*
to :INTERPRET to enable it.

http://www.sbcl.org/manual/#Interpreter

juki··on Lisp Quickstart
Typically yes. You should be able to run the test suite through ASDF. For example

    CL-USER> (ql:quickload :trivia)
    ... loads ...
    CL-USER> (asdf:test-system :trivia)
    ... test output ...
But unfortunately not all libraries set up their test-ops properly. You can usually find a readme at ~/quicklisp/dists/quicklisp/software/... which might have instructions for running tests.
juki··on Lisp Quickstart
Common Lisp is a very stable language. The standard hasn't changed in twenty years, so (unlike many other languages) old code is still perfectly good. Libraries that haven't been updated in a decade still work just as well as they did a decade ago.
juki··on Text Editor Performance Comparison
The Emacs equivalent would be

    M-x replace-regexp word1\(.*\)word2$ RET word3\1word4 RET
Assuming you have `replace-regexp` bound to a key, it's practically the same. Works on the whole buffer (by default), or the region (if selected).
juki··on Modern C++ and Lisp Programming Style
The DEFGENERIC line is wrong. It can't have a body like that. It should be something like

    (defgeneric xplusone (x)
      (:method (x) (+ 1 x)))
Also, generic functions are slower than regular functions (due to dynamic dispatch), so using them for type optimization would be rather counterproductive.
juki··on Emacs org-mode examples and cookbook
You can always put different tasks to different files (per project for example).

There no need to hunt for todos; use `C-c \` (or `C-c /` for more options) to create a sparse tree. It supports the same queries as agenda tag searches. For example, `/!` to show all unfinished tasks, or `/TODO` for just the ones with TODO as the keyword.

You can also use the timeline view with a prefix argument to see tasks in the current file (`C-u C-c a L`). Or you can restrict other agenda views to the current buffer (`C-c a < t` for a task list). Custom agenda commands can also specify their own set of agenda files (they can also be chosen by a function whenever the agenda view is created).

← PreviousPage 5 of 6Next →