call-with-current-continuation-for-C-programmers

Once you've got a continuation object, calling it as say (cont 123) is like a C code longjmp(jbuf, 123). It's a jump back to the original call/cc point, and the return value from the call/cc is the 123 in the invoking call, just like setjmp returns the value passed to longjmp. In Scheme of course any object can be "returned" in this way (and even values? for more than one object), not just a single int.

setjmp/longjmp 類比的 call/cc

Chapter 10. Code case study: parsing a binary data format

Why would I want to do this?

So I can reuse functions built on fmap with other datatypes
To clarify my thought

Why would I not want to do this?

Because I'm not reusing said functions
Because I want to be able to find the function definition quickly (treeMap is unique, fmap isn't)

Detailing pros and cons help people to make the right decisions for their circumstances.

Type-signature vs. function equation in Haskell - Stack Overflow

After thinking some more about this, I think the full explanation should be something along the lines of:

An Haskell function can only accept a single argument and return one parameter. Haskell allows us to pretend that several arguments are passed, but this form is treated as a series of nested lambda functions.

f x y = x + y

is treated as

(1) f = \x -> \y -> x + y

This treatment is true for lambda functions as well \x y -> x + y is treated as \x -> \y -> x + y

This allows us to treat type declaration as left-associative, that is: f :: Int -> Int -> Int is actually f :: (Int -> (Int -> Int)) which fits exactly to (1) above: f has no arguments, but is returning a function which accepts Int. This function in turn returns a function which accepts another Int, and returns an Int.

This means that if we want to return a function from a function, we don't have to do anything special, since that's Haskell's "default" mode.

This also means that given the type declaration f :: Int -> Int -> Int We can write f's implementatin ("equation") with 0, 1 or 2 parameters. If one or two parameter are specified, the compiler will generate the necessary lambdas to comply with the form f :: (Int -> (Int -> Int))

f = \x -> \y -> x + yf x = \y -> x + y  -- \x -> is generatedf x y = x + y -- \x -> \y is generated

But in each of these cases, the function application appearing to accept two parameters will compile successfully, since it will always be translated to the first form, e.g.

f 4 5 --> (\x -> (\y -> x + y) 5 ) 4

Where the inner function application will return the curried form (x + 5)

This enables partial function application, where we can give f just one parameter and get back a partial function.

Also, changing the precedence in the function type:

f'' :: (Int -> Int) -> Int

changes the meaning - we accept a function getting an Int and returning one as the single parameter, and return an Int.
Assuming we've defined this function somewhere, then calling this function with Integer parameters, e.g.

f'' 4 5

will not compile.

Edit:

Also, even if the last arguments are in parenthesis, or are a type declaration, this holds.

E.g., in the following, the last pair of parenthesis is optional, since if they weren't there the compiler would put them anyway to get to the "lambda'd" form.

t4 :: (Int -> Int) -> (Int -> Int)t4 f i = f i + i

Can be applied thus:

t4 (\x -> x*10) 5

Also, given:

type MyIntInt = Int -> Int

Then:

t5 :: MyIntInt -> MyIntInt

Is equivalent to t4, but confusing, since the meaning of MyIntInt is different in both places. The first one is the type of the first parameter.
The second one is "expanded" into Int -> Int (probably because of the right-associativity of the operator), which means that t5 can appear to accept 0 to 2 parameters in the function equation and function application (while actually always accepting 0 and returning embedded lambdas, as I've detailed above).

E.g. we can write t5 just like t4:

t5 f i = f i + i

解釋為什麼 type signature 和定義看起來不一樣的 function 可以 compile 得過

Chapter 9. I/O case study: a library for searching the filesystem

Kushlendra Mishra:

Mostly, types and precedence:

Prelude> :i ($)
($) :: (a -> b) -> a -> b -- Defined in GHC.Base
infixr 0 $
Prelude> :i (.)
(.) :: (b -> c) -> (a -> b) -> a -> c -- Defined in GHC.Base
infixr 9 .

The types mean that ($) applies an argument to a function while (.) takes two functions to combine. The "infixr" lines mean that (.) binds much tighter than ($).

"f y $ z" passes arguments "y" and "z" to function "f". Notice that ($) does its thing after "y" is passed to "f".
It's the same as "x y (z)", which is mostly useful when "z" is a really long or involves lots of parentheses.

"f y . z " passes the function "y . z" to function "f". Notice that "y" and "z" are combined before being passed to "f".
It's the same as "f (\x -> y (z x))"

Special Characters

-

redirection from/to stdin or stdout [dash].

bash$ cat -
abc
abc

...

Ctl-D

As expected, cat - echoes stdin, in this case keyboarded user input, to stdout. But, does I/O redirection using - have real-world applications?

(cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)
# Move entire file tree from one directory to another
# [courtesy Alan Cox <a.cox@swansea.ac.uk>, with a minor change]

# 1) cd /source/directory
#    Source directory, where the files to be moved are.
# 2) &&
#   "And-list": if the 'cd' operation successful,
#    then execute the next command.
# 3) tar cf - .
#    The 'c' option 'tar' archiving command creates a new archive,
#    the 'f' (file) option, followed by '-' designates the target file
#    as stdout, and do it in current directory tree ('.').
# 4) |
#    Piped to ...
# 5) ( ... )
#    a subshell
# 6) cd /dest/directory
#    Change to the destination directory.
# 7) &&
#   "And-list", as above
# 8) tar xpvf -
#    Unarchive ('x'), preserve ownership and file permissions ('p'),
#    and send verbose messages to stdout ('v'),
#    reading data from stdin ('f' followed by '-').
#
#    Note that 'x' is a command, and 'p', 'v', 'f' are options.
#
# Whew!



# More elegant than, but equivalent to:
#   cd source/directory
#   tar cf - . | (cd ../dest/directory; tar xpvf -)
#
#     Also having same effect:
# cp -a /source/directory/* /dest/directory
#     Or:
# cp -a /source/directory/* /source/directory/.[^.]* /dest/directory
#     If there are hidden files in /source/directory.

bunzip2 -c linux-2.6.16.tar.bz2 | tar xvf -
#  --uncompress tar file--      | --then pass it to "tar"--
#  If "tar" has not been patched to handle "bunzip2",
#+ this needs to be done in two discrete steps, using a pipe.
#  The purpose of the exercise is to unarchive "bzipped" kernel source.

Note that in this context the "-" is not itself a Bash operator, but rather an option recognized by certain UNIX utilities that write to stdout, such as tar, cat, etc.

bash$ echo "whatever" | cat -
whatever

Where a filename is expected, - redirects output to stdout (sometimes seen with tar cf), or accepts input from stdin, rather than from a file. This is a method of using a file-oriented utility as a filter in a pipe.

bash$ file
Usage: file [-bciknvzL] [-f namefile] [-m magicfiles] file...
By itself on the command-line, file fails with an error message.

Add a "-" for a more useful result. This causes the shell to await user input.

bash$ file -
abc
standard input:              ASCII text



bash$ file -
#!/bin/bash
standard input:              Bourne-Again shell script text executable
Now the command accepts input from stdin and analyzes it.

The "-" can be used to pipe stdout to other commands. This permits such stunts as prepending lines to a file.

Using diff to compare a file with a section of another:

grep Linux file1 | diff file2 -

Finally, a real-world example using - with tar.

Example 3-4. Backup of all files changed in last day

#!/bin/bash

#  Backs up all files in current directory modified within last 24 hours
#+ in a "tarball" (tarred and gzipped file).

BACKUPFILE=backup-$(date +%m-%d-%Y)
#                 Embeds date in backup filename.
#                 Thanks, Joshua Tschida, for the idea.
archive=${1:-$BACKUPFILE}
#  If no backup-archive filename specified on command-line,
#+ it will default to "backup-MM-DD-YYYY.tar.gz."

tar cvf - `find . -mtime -1 -type f -print` > $archive.tar
gzip $archive.tar
echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"."


#  Stephane Chazelas points out that the above code will fail
#+ if there are too many files found
#+ or if any filenames contain blank characters.

# He suggests the following alternatives:
# -------------------------------------------------------------------
#   find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
#      using the GNU version of "find".


#   find . -mtime -1 -type f -exec tar rvf "$archive.tar" '{}' \;
#         portable to other UNIX flavors, but much slower.
# -------------------------------------------------------------------


exit 0

Caution

Filenames beginning with "-" may cause problems when coupled with the "-" redirection operator. A script should check for this and add an appropriate prefix to such filenames, for example ./-FILENAME, $PWD/-FILENAME, or $PATHNAME/-FILENAME.

If the value of a variable begins with a -, this may likewise create problems.

var="-n"
echo $var                
# Has the effect of "echo -n", and outputs nothing.

混了那麼多年,現在才知道原來 - (dash) 是這樣用的… Orz

可以自己來的 apps 乾淨免安裝

FileZilla

  • 下載 filezilla 的 zip 版本
  • 解開
  • docs/fzdefaults.xml.sample 複製到與 exe 同層的目錄(去掉 .sample)
  • 改裡面的 %somedir% 成你放 filezilla 的位置

這樣子的 filezilla 執行後,就不會加 registry 也不會放東西在 %AppData% 中了,
全部都是用 xml 存。

uTorrent

  • 下載 utorrent
  • 將 utorrent.exe 放在你要放的資料夾內
  • 建立一個空檔 settings.dat

這樣子執行 utorrent.exe 後,所有設定都會被寫在該資料夾內,
不會放任何東西在你的 %AppData% 中。

MPC HomeCinema

  • 下載 mpc-hc 的 7z 版本
  • 某些 filter/scaler 會需要 d3dx9_xx.dll
  • 下載 DirectX Distributable End-User Runtime
  • 解開找裡面的 d3dx9_xx.dll (xx 愈大愈好)
  • 丟到 mpc-hc 解開的目錄中即可

Real Alternative

因為我是 64bit,mpchc/ffdshow 都是用 64bit 的了,
要多裝一個 mpchc-32 加上 real alternative 太髒了,
因此可以選擇改用 nightly build 版本的 VLC (1.2+)
已經可以正常放 rmvb。
完全 portable。 

Understanding Ruby Singleton Classes - Contextual Development

foobar = Array.new

def foobar.size
  "Hello World!"
end

foobar.size  # => "Hello World!"
foobar.class # => Array

bizbat = Array.new
bizbat.size  # => 0
When you add a method to a specific object, Ruby inserts a new, anonymous class into the inheritance hierarchy as a container to hold these types of methods.

More Ways to Skin a Singleton:

module Foo
  def foo
    "Hello World!"
  end
end

foobar = []
foobar.extend(Foo)
foobar.singleton_methods # => ["foo"]

or

foobar = []

class << foobar
  def foo
    "Hello World!"
  end
end

foobar.singleton_methods # => ["foo"]

Ruby classes are actually objects instantiated from the Class class. Their names are constants that point to this object instantiated from the Class class. While this object holds the instance methods for objects instantiated from it, its so-called class methods are kept on a singleton class.

在 ruby 中,直接對一個 object(e.g. from Array.new) 定義 method 的時候,

  1. ruby 就會從 Array 繼承一個 anonymous class 
  2. 將你定義的 method 寫在 anonymous class 裡面 
  3. 然後將 object 的 class 換成 anonymous class

此時,這個 anonymous class 就是一個 singleton class。
但是從外部是看不到的,會認為 object 是一個 class Array 的東西。

所有在 singleton class 中的 methods 就叫做 singleton methods。

實際上 ruby 只有 instance methods,所有的 class methods 都是 singleton class (between class and Class) 的 singleton methods。

singleton methods 在現實中會用的情形之一就是 test mocking。

 

由這個機制延伸來理解 Object#extend首先了解 extend 與 include 的基本用途後,

會看到 extend (新增 methods 到目前 "instance")的用法是:

 

obj = Object.new
obj.extend InstanceMethods
puts obj.an_instance_method      # >> You called an_instance_method on Object

 

在 irb 中自己打一遍,就能發現,所有被 extend 加入的 methods 都會顯示在 obj.singleton_methods 中。

也就是說,對 obj 作 extend 的意思與最上面的「直接對 object 再定義 methods 」的最後結果是一樣的!

都是產生一個 singleton class,把加入的 method 都放到 class 裡面變成 singleton_methods。

 

如果是寫成這樣:

class MyClass
  include InstanceMethods
  extend ClassMethods
end

在這裡的 extend ClassMethods 與 MyClass.new.extend(ClassMethods) 是一樣的意思,能直接寫在 class 定義裡面是因為 class 繼承自 Object,而 Object#extend

也就是說,與上面一樣,就是產生 singleton methods,

因為這裡的對象是 class MyClass,這些 singleton methods 也就是所謂 MyClass 的 class methods。

所以這行就是定義 class methods。

有了這個觀察到的現象,就不難理解這樣的 code:

module Rake  include Test::Unit::Assertions  def run_tests # etc.  end  # what does the next line do?  extend selfend

在這裡的 extend selfRake.new.extend(Rake) 是一樣的意思,

Rake.new.extend(Rake) 的結果就是產生了一個 singleton class,裡面的 methods 都是自己原來的 singleton methods。

也就是說,這行就是直接跟 ruby 說,我在這個 module Rake 裡面定義的所有 method 就是我的 module method(class method of class Module)。

→→→終極簡寫法。

Iterators and generators - MDC Doc Center

While custom iterators are a useful tool, their creation requires careful programming due to the need to explicitly maintain their internal state. Generators provide a powerful alternative: they allow you to define an iterative algorithm by writing a single function which can maintain its own state.

A generator is a special type of function that works as a factory for iterators. A function becomes a generator if it contains one or more yield expressions.

Javascript 的作法:
我們提供 Iterator 物件,也讓你用 prototype 來定義 custom iterator

如果你不想自己寫,我們也提供 iterator 的 factory,generator,
此時的作法就要用關鍵字 yield

What is the difference between an Iterator and a Generator? - Stack Overflow

An iterator traverses a collection one at a time.

A generator generates a sequence, one item at a time.

You might for example, iterate over the result of a generator...

Generators are iterators, but not all iterators are generators.

An iterator is typically something that has a next method to get the next element from a stream. A generator is an iterator that is tied to a function.

A generator is an implementation of an iterator.

 王小旺 
@ 
@ 其實我沒仔細研究過,我的理解是:「iterator」是用途、「generator」是作法。 :/