Cannot create apply function with static language?

前端 未结 12 887
梦谈多话
梦谈多话 2021-02-04 02:09

I have read that with a statically typed language like Scala or Haskell there is no way to create or provide a Lisp apply function:

(apply #\'+ (lis         


        
12条回答
  •  日久生厌
    2021-02-04 02:56

    A full APPLY is difficult in a static language.

    In Lisp APPLY applies a function to a list of arguments. Both the function and the list of arguments are arguments to APPLY.

    • APPLY can use any function. That means that this could be any result type and any argument types.

    • APPLY takes arbitrary arguments in arbitrary length (in Common Lisp the length is restricted by an implementation specific constant value) with arbitrary and possibly different types.

    • APPLY returns any type of value that is returned by the function it got as an argument.

    How would one type check that without subverting a static type system?

    Examples:

    (apply #'+ '(1 1.4))   ; the result is a float.
    
    (apply #'open (list "/tmp/foo" :direction :input))
    ; the result is an I/O stream
    
    (apply #'open (list name :direction direction))
    ; the result is also an I/O stream
    
    (apply some-function some-arguments)
    ; the result is whatever the function bound to some-function returns
    
    (apply (read) (read))
    ; neither the actual function nor the arguments are known before runtime.
    ; READ can return anything
    

    Interaction example:

    CL-USER 49 > (apply (READ) (READ))                        ; call APPLY
    open                                                      ; enter the symbol OPEN
    ("/tmp/foo" :direction :input :if-does-not-exist :create) ; enter a list
    #                   ; the result
    

    Now an example with the function REMOVE. We are going to remove the character a from a list of different things.

    CL-USER 50 > (apply (READ) (READ))
    remove
    (#\a (1 "a" #\a 12.3 :foo))
    (1 "a" 12.3 :FOO)
    

    Note that you also can apply apply itself, since apply is a function.

    CL-USER 56 > (apply #'apply '(+ (1 2 3)))
    6
    

    There is also a slight complication because the function APPLY takes an arbitrary number of arguments, where only the last argument needs to be a list:

    CL-USER 57 > (apply #'open
                        "/tmp/foo1"
                        :direction
                        :input
                        '(:if-does-not-exist :create))
    #
    

    How to deal with that?

    • relax static type checking rules

    • restrict APPLY

    One or both of above will have to be done in a typical statically type checked programming language. Neither will give you a fully statically checked and fully flexible APPLY.

提交回复
热议问题