Visto nel Web – 309

OK, di corsa ecco cosa ho wisto nel Web.

Very good article by @Kantrowitz. And yet, FB’s stock “is trading at historical highs”
#:ditte #:sicurezza, spionaggio, virus
::: fabiochiusi

Sorting Visualizations
#:algoritmi, codice
::: algoritmic

New Video Peeks ‘Inside the Head’ of Perl Creator Larry WalL
#:linguaggi di programmazione
::: Slashdot

Google Accused of Racketeering. Lawsuit Claims ‘Pattern’ Of Trade Secret Thefts
#:ditte
::: Slashdot

Quesito con la Susi n. 945
Mauro rockz 👽, anzi di più 😁
#:lisp(s)
::: Muapna

Wikipedia shapes language in science papers
#:Web, Internet
::: Nature

8 Reasons to Learn and Switch to Linux
#:sistemi operativi
::: dcavedon

Intel CPU History
#:storia
::: Donearm

Writing A CSS-in-JS Library From Scratch
#:programming, codice, snippet
::: reactdayberlin

Microsoft Develops New Programming Language For Quantum Computers
#:linguaggi di programmazione
::: Slashdot

Declaring the 3rd Saturday of October (21st October this year) the International Day of Repair
#:hardware
::: hkoundi

Linux Now Has its First Open Source RISC-V Processor
#:innovazioni, futuro
::: Slashdot

The @racketlang community is without a doubt the friendliest, most inviting community in programming I’ve seen. Thanks for a great weekend
ci sono diverse ore di videos sulla #RacketCon 😁😁😁
#:lisp(s)
::: technomancy ::: lexi_lambda ::: hashtag

Min – A smarter web browser
#:Web, Internet
::: Donearm

Take a few minutes to complete our Python Developers Survey 2017 and win valuable prizes!
#:linguaggi di programmazione
::: ThePSF

Is the rise of open source connected to a decline in selfishness?
#:free open source software
::: lucaciavatta

What the data says about how Linux kernel developers collaborate
#:free open source software
::: lucaciavatta

SIA-2017-L02: Introduzione ai sistemi informativi
c’è (ci sarà) tutto il corso su YouTube 😁
#:scuola, educazione
::: fulcorno

Microsoft ‘Was Sick’, CEO Satya Nadella Says In New Book
#:ditte
::: Slashdot

New MIT system lets you see around corners with your iPhone
#:artificial intelligence
::: MIT_CSAIL

#Librem5 ce l’ha fatta, raggiunto 1,5 mln $, progetto finanziato al 100% (e ancora 14 gg!)
#:free open source software
::: dcavedon

How to download files in parallel?
#tools
::: The Ubuntu Incident

How a Microsoft docs team increased openness and improved collaboration
#:ditte #:free open source software
::: lucaciavatta

Breve ritratto del potere, 2017
#:protagonisti
::: fabiochiusi

Roma e la transizione al #softwarelibero
#:free open source software
::: Roma_Semplice

Tools are the answer
questa cosa va avanti divisiva da un po’
#:artificial intelligence
::: johnregehr

The Impressive Growth of R
#:linguaggi di programmazione
::: StackOverflow

North Korean Hackers Stole U.S.-South Korean Military Plans, Lawmaker Says
#:sicurezza, spionaggio, virus
::: Slashdot

How Does Microsoft Avoid Being the Next IBM?
#:ditte
::: Slashdot

I’m not correcting someone who was wrong on the internet
certo! 😁
#:programming, codice, snippet
::: wallingf

A doorbell powered by Amazon to let the delivery person coming inside your home?
#:artificial intelligence
::: btabaka

Perl turns 30 and its community continues to thrive
mi ricordo che legendo una recensione di Perl 1.0 mi ero detto che sarebbe stato proprio quel che mi serviva 😜
#:storia
::: lucaciavatta

Net neutrality: Key zero rating decision made by Germany
#:Web, Internet
::: superglaze

You heard it here first, folks. CSV is an attack vector
forse solo con Windows, ma non ne sono sicuro
#:sicurezza, spionaggio, virus
::: brandonlrice

Hey Twitter, delete racism and anti-American sentiments or we’re going to regulate you
#:social media
::: fabiochiusi

GuIT Channel
#:tools, componenti software
::: Robitex

Clustergrammer, web-based heatmap tool for high-dimensional biological data
#:programming, codice, snippet
::: ScientificData

Google Will Hit 100 Percent Renewable Energy This Year
#:ditte
::: Slashdot

New: Facebook says the spread of a fake news story drops by 80% after a fact checker labels it false
#:fake news, bufale
::: CraigSilverman

Getting Started with Flatpak
#:tools, componenti software
::: lucaciavatta

Google is growing to 5,000 people in Zurich
#:ditte
::: marcelsalathe

Zuckerberg prova a invertire il senso comune: la realtà virtuale non isola, è “social” – anzi, il sostrato dei social del futuro
tenterò in futuro di occuparmi di meno di queste notizie
#:protagonisti #:social media
::: fabiochiusi::: fabiochiusi::: fabiochiusi::: Mlsif::: fabiochiusi

no data on how a new right increase revenues to sustain a free & pluralist press
#:copyright e brevetti
::: communia_eu

IMO yes. Apparently people embed Chromium these days and the action is in JavaScript frameworks
#:programming, codice, snippet
::: gvanrossum

Announcing Rust 1.21
#:linguaggi di programmazione
::: rustlang

Algorithm automatically retouches photos in real-time
#:algoritmi, codice
::: MIT_CSAIL

Can democracy survive Facebook and the ‘chaos monkeys’?
#:social media
::: antoniogm

We’re Too Wise For Robots To Take Our Jobs, Alibaba’s Jack Ma Says
#:innovazioni, futuro
::: Slashdot

Even Pokémon Go used by extensive Russian-linked meddling effort
#:sicurezza, spionaggio, virus
::: fabiochiusi

@d1gi proved Russia’s disinfo campaign on Facebook was wider than they admit
#:sicurezza, spionaggio, virus
::: Anthony

The Real Inside Story of How Commodore Failed
#:storia
::: Slashdot

Check disk usage at the command line with du
#:tools, componenti software
::: lucaciavatta

Twitter Is Crawling With Bots and Lacks Incentive To Expel Them
#:social media
::: Slashdot::: fabiochiusi

Google Bombs Are Our New Normal
#:sicurezza, spionaggio, virus
::: Slashdot

Science and Technology links
#:artificial intelligence #:innovazioni, futuro
::: Daniel Lemire

Woz Wants To Retrain You For a Career in Tech
chissà… ne ha fatte di buone, ottime e anche altre
#:protagonisti
::: Slashdot

Latest iOS Update Shows Apple Can Use Software To Break Phones Repaired By Independent Shops
#:ditte
::: Slashdot

Annunci

Haskell – 13 – elementi fondamentali – 7

Continuo da qui, copio qui, scrollare fino a “Exercises”.

3. Define a function isLower :: Char -> Bool which returns True if a given character is a lower case letter. You can use the fact that characters are ordered, and for all lower case letters ch we have ′a′ ≤ ch and ch ≤ ′z′. Alternatively, you can use the fact that ['a'..'z'] evaluates to a list containing all lower case letters.

isl-1.hs

isLower :: Char -> Bool

isLower x = 'a' <= x && x <= 'z'
Prelude> :l isl-1
[1 of 1] Compiling Main             ( isl-1.hs, interpreted )
Ok, 1 module loaded.
*Main> isLower 'j'
True
*Main> isLower 'a'
True
*Main> isLower 'z'
True
*Main> isLower '0'
False
*Main> isLower 'T'
False

Io la modificherei in questo modo (sapete, vengo da lontano (Fortran)😊)

isl-2.hs

isLower :: Char -> Bool

isLower x = x >= 'a' && x <= 'z'
*Main> :l isl-2
[1 of 1] Compiling Main             ( isl-2.hs, interpreted )
Ok, 1 module loaded.
*Main> isLower 'j'
True
*Main> isLower 'T'
False
*Main> isLower '.'
False
*Main> isLower '~'
False

Ma ancora più sexy questa versione

isl-3.hs

isLower :: Char -> Bool

isLower x = elem x ['a'..'z']
*Main> :l isl-3
[1 of 1] Compiling Main             ( isl-3.hs, interpreted )
Ok, 1 module loaded.
*Main> isLower 'l'
True
*Main> isLower 'U'
False

4. Write a function mangle :: String -> String which removes the first letter of a word and attaches it at the end. If the string is empty, mangle should simply return an empty string:

mangle "Hello" ⇒ "elloH"
mangle "I" ⇒ "I"
mangle "" ⇒  ""

Non ci sto riuscendo. Uh! capito 😁, dopo diversi tentativi (che non racconto, già dimenticati)

mgl.hs

mangle :: String -> String

mangle x = if (length x <= 1) then x else tail x ++ [head x]
*Main> :l mgl
[1 of 1] Compiling Main             ( mgl.hs, interpreted )
Ok, 1 module loaded.
*Main> mangle "Hello"
"elloH"
*Main> mangle "I"
"I"
*Main> mangle ""
""

Personalmente preferisco scriverlo con le  guardie  guards:

mgl-g

mangle :: String -> String

mangle x | (length x <= 1) = x 
         | otherwise = tail x ++ [head x]

Resta da fare il 5. Prossimamente, forse 😊

🤢

Julia – 96 – Eseguire codice C e Fortran – 6

Continuo da qui, copio qui.

Qualche esempi ci wrappers C
Here is a simple example of a C wrapper that returns a Ptr type:

mutable struct gsl_permutation
end

# The corresponding C signature is
#     gsl_permutation * gsl_permutation_alloc (size_t n);
function permutation_alloc(n::Integer)
    output_ptr = ccall(
        (:gsl_permutation_alloc, :libgsl), # name of C function and library
        Ptr{gsl_permutation},              # output type
        (Csize_t,),                        # tuple of input types
        n                                  # name of Julia variable to pass in
    )
    if output_ptr == C_NULL # Could not allocate memory
        throw(OutOfMemoryError())
    end
    return output_ptr
end

The GNU Scientific Library (here assumed to be accessible through :libgsl) defines an opaque pointer, gsl_permutation *, as the return type of the C function gsl_permutation_alloc(). As user code never has to look inside the gsl_permutation struct, the corresponding Julia wrapper simply needs a new type declaration, gsl_permutation, that has no internal fields and whose sole purpose is to be placed in the type parameter of a Ptr type. The return type of the ccall is declared as Ptr{gsl_permutation}, since the memory allocated and pointed to by output_ptr is controlled by C (and not Julia).

The input n is passed by value, and so the function’s input signature is simply declared as (Csize_t,) without any Ref or Ptr necessary. (If the wrapper was calling a Fortran function instead, the corresponding function input signature should instead be (Ref{Csize_t},), since Fortran variables are passed by reference.) Furthermore, n can be any type that is convertable to a Csize_t integer; the ccall implicitly calls Base.cconvert(Csize_t, n).

Here is a second example wrapping the corresponding destructor:

# The corresponding C signature is
#     void gsl_permutation_free (gsl_permutation * p);
function permutation_free(p::Ref{gsl_permutation})
    ccall(
        (:gsl_permutation_free, :libgsl), # name of C function and library
        Void,                             # output type
        (Ref{gsl_permutation},),          # tuple of input types
        p                                 # name of Julia variable to pass in
    )
end

Here, the input p is declared to be of type Ref{gsl_permutation}, meaning that the memory that p points to may be managed by Julia or by C. A pointer to memory allocated by C should be of type Ptr{gsl_permutation}, but it is convertable using Base.cconvert() and therefore can be used in the same (covariant) context of the input argument to a ccall. A pointer to memory allocated by Julia must be of type Ref{gsl_permutation}, to ensure that the memory address pointed to is valid and that Julia’s garbage collector manages the chunk of memory pointed to correctly. Therefore, the Ref{gsl_permutation} declaration allows pointers managed by C or Julia to be used.

If the C wrapper never expects the user to pass pointers to memory managed by Julia, then using p::Ptr{gsl_permutation} for the method signature of the wrapper and similarly in the ccall is also acceptable.

Here is a third example passing Julia arrays:

# The corresponding C signature is
#    int gsl_sf_bessel_Jn_array (int nmin, int nmax, double x,
#                                double result_array[])
function sf_bessel_Jn_array(nmin::Integer, nmax::Integer, x::Real)
    if nmax < nmin
        throw(DomainError())
    end
    result_array = Vector{Cdouble}(nmax - nmin + 1)
    errorcode = ccall(
        (:gsl_sf_bessel_Jn_array, :libgsl), # name of C function and library
        Cint,                               # output type
        (Cint, Cint, Cdouble, Ref{Cdouble}),# tuple of input types
        nmin, nmax, x, result_array         # names of Julia variables to pass in
    )
    if errorcode != 0
        error("GSL error code $errorcode")
    end
    return result_array
end

The C function wrapped returns an integer error code; the results of the actual evaluation of the Bessel J function populate the Julia array result_array. This variable can only be used with corresponding input type declaration Ref{Cdouble}, since its memory is allocated and managed by Julia, not C. The implicit call to Base.cconvert(Ref{Cdouble}, result_array) unpacks the Julia pointer to a Julia array data structure into a form understandable by C.

Note that for this code to work correctly, result_array must be declared to be of type Ref{Cdouble} and not Ptr{Cdouble}. The memory is managed by Julia and the Ref signature alerts Julia’s garbage collector to keep managing the memory for result_array while the ccall executes. If Ptr{Cdouble} were used instead, the ccall may still work, but Julia’s garbage collector would not be aware that the memory declared for result_array is being used by the external C function. As a result, the code may produce a memory leak if result_array never gets freed by the garbage collector, or if the garbage collector prematurely frees result_array, the C function may end up throwing an invalid memory access exception.

Garbage collection in modo sicuro
When passing data to a ccall, it is best to avoid using the pointer() function. Instead define a convert method and pass the variables directly to the ccall. ccall automatically arranges that all of its arguments will be preserved from garbage collection until the call returns. If a C API will store a reference to memory allocated by Julia, after the ccall returns, you must arrange that the object remains visible to the garbage collector. The suggested way to handle this is to make a global variable of type Array{Ref,1} to hold these values, until the C library notifies you that it is finished with them.

🤢

Haskell – 12 – elementi fondamentali – 6

Continuo da qui, copio qui, scrollare fino a “Exercises”.

Esercizi
1. Write a function sort2 :: Ord a => a -> a -> (a, a) which accepts two Int values as arguments and returns them as a sorted pair, so that sort2 5 3 is equal to (3,5). How can you define the function using a conditional, how can you do it using guards?

es1-1.hs

sort2 :: Ord a => a -> a -> (a, a)
sort2 x y = if x >= y then (y, x) else (x, y)
Prelude> :l es1-1
[1 of 1] Compiling Main             ( es1-1.hs, interpreted )
Ok, 1 module loaded.
*Main> sort2 5 3
(3,5)
*Main> sort2 1 8
(1,8)

es1-2.hs

sort2 :: Ord a => a -> a -> (a, a)
sort2 x y | x >= y = (y, x) 
          | x < y  = (x, y)
*Main> :l es1-2
[1 of 1] Compiling Main             ( es1-2.hs, interpreted )
Ok, 1 module loaded.
*Main> sort2 5 3
(3,5)
*Main> sort2 1 8
(1,8)

2. Consider a function

almostEqual :: Eq a => (a, a) -> (a, a) -> Bool

which compares the values of two pairs. It returns True if both pairs contain the same values, regardless of the order. For example, almostEqual (3,4) (4,3) is True, but almostEqual (3,4) (3,5) is False. Which of the following definitions return the correct value? Which of the definitions would you consider good style? Why?

(The operator (&&) is logical ”and”, the operator (||) is logical ’or’, and (==) tests if two values are equal. The first two are of type Bool -> Bool -> Bool; the third is of type Eq a => a -> a -> Bool.)

almostEqual (x1, y1) (x2, y2)
  | (x1 == x2) && (y1 == y2) = True
  | (x1 == y2) && (y1 == x2) = True
  | otherwise                = False

almostEqual (x1, y1) (x2, y2)
  | (x1 == x2) = (y1 == y2) 
  | (x1 == y2) = (y1 == x2) 
  | otherwise  = False

almostEqual pair1 pair2 
  = (pair1 == pair2) || (swap pair1 == pair2)
  where 
    swap (x,y) = (y,x)

almostEqual pair1 pair2 
  = (pair1 == pair2) || (swap pair1 == swap pair2)
  where 
    swap (x,y) = (y,x)

almostEqual (x1, y1) (x2, y2) 
  = if (x1 == x2) 
      then
        if (y1 == y2) 
          then True
          else False
      else 
        if (x1 == y2) 
          then 
            if (x2 == y1)
              then True
              else False
          else False

La prima versione (es2-a.hs) è OK

es2-a.hs

almostEqual :: Eq a => (a, a) -> (a, a) -> Bool

almostEqual (x1, y1) (x2, y2)
  | (x1 == x2) && (y1 == y2) = True
  | (x1 == y2) && (y1 == x2) = True
  | otherwise                = False
*Main> :l es2-a
[1 of 1] Compiling Main             ( es2-a.hs, interpreted )
Ok, 1 module loaded.
*Main> almostEqual (3,4) (4,3)
True
*Main> almostEqual (3,4) (3,5)
False

La seconda (es2-b.hs) anche.

es2-b.hs

almostEqual :: Eq a => (a, a) -> (a, a) -> Bool

almostEqual (x1, y1) (x2, y2)
  | (x1 == x2) = (y1 == y2)
  | (x1 == y2) = (y1 == x2)
  | otherwise  = False
Prelude> :l es2-b
[1 of 1] Compiling Main             ( es2-b.hs, interpreted )
Ok, 1 module loaded.
*Main> almostEqual (3,4) (4,3)
True
*Main> almostEqual (3,4) (3,5)
False

perché ritorna il valore dato dall’operatore = se questo è True; se False ritorna la guard finale (otherwise). La prima è (forse) più chiara, la seconda (credo) più haskelliana. Anzi, ripensandoci la seconda è molto più bella.

La terza (es2-c.hs) è ancora più haskelliana, deriva dalla seconda:

es2-c.hs

almostEqual :: Eq a => (a, a) -> (a, a) -> Bool

almostEqual pair1 pair2
  = (pair1 == pair2) || (swap pair1 == pair2)
  where 
    swap (x,y) = (y,x)
*Main> :l es2-c
[1 of 1] Compiling Main             ( es2-c.hs, interpreted )
Ok, 1 module loaded.
*Main> almostEqual (3,4) (4,3)
True
*Main> almostEqual (3,4) (3,5)
False

la quarta (es2-d.hs) non è corretta per lo swap di entrambe le pair in quanto devo verificare se una è il rovescio dell’altra.

es2-d.hs

almostEqual :: Eq a => (a, a) -> (a, a) -> Bool

almostEqual pair1 pair2
  = (pair1 == pair2) || (swap pair1 == swap pair2)
  where 
    swap (x,y) = (y,x)

risultati non corretti

*Main> :l es2-d
[1 of 1] Compiling Main             ( es2-d.hs, interpreted )
Ok, 1 module loaded.
*Main> almostEqual (3,4) (4,3)
False
-- risultato NON corretto!!!
*Main> almostEqual (3,4) (3,5)
False
*Main> almostEqual (3,4) (3,4)
True

la quinta (es2-e.hs) è OK ma primitiva, sembra Python (o peggio)

es2-e.hs

almostEqual :: Eq a => (a, a) -> (a, a) -> Bool

almostEqual (x1, y1) (x2, y2) 
  = if (x1 == x2) 
      then
        if (y1 == y2) 
          then True
          else False
      else 
        if (x1 == y2) 
          then 
            if (x2 == y1)
              then True
              else False
          else False
*Main> :l es2-e
[1 of 1] Compiling Main             ( es2-e.hs, interpreted )
Ok, 1 module loaded.
*Main> almostEqual (3,4) (4,3)
True
*Main> almostEqual (3,4) (3,5)
False

Ci sono ancora 3 esercizi, per il prossimo post 😊

🤢

Julia – 95 – Eseguire codice C e Fortran – 5

Continuo da qui, copio qui.

Mappare funzioni C in Julia
guida alla traduzione degli argomenti di ccall e cfunction
For translating a C argument list to Julia:

  • T, where T is one of the primitive types: char, int, long, short, float, double, complex, enum or any of their typedef equivalents
    T, where T is an equivalent Julia Bits Type (per the table above)
    if T is an enum, the argument type should be equivalent to Cint or Cuint
    argument value will be copied (passed by value)
  • struct T (including typedef to a struct)
    T, where T is a Julia leaf type
    argument value will be copied (passed by value)
  • void*
    depends on how this parameter is used, first translate this to the intended pointer type, then determine the Julia equivalent using the remaining rules in this list
    this argument may be declared as Ptr{Void}, if it really is just an unknown pointer
  • jl_value_t*
    Any
    argument value must be a valid Julia object
    currently unsupported by cfunction()
  • jl_value_t**
    Ref{Any}
    argument value must be a valid Julia object (or C_NULL)
    currently unsupported by cfunction()
  • T*
    Ref{T}, where T is the Julia type corresponding to T
    argument value will be copied if it is an isbits type otherwise, the value must be a valid Julia object
  • (T*)(...) (e.g. a pointer to a function)
    Ptr{Void} (you may need to use cfunction() explicitly to create this pointer)
    ... (e.g. a vararg)
    T..., where T is the Julia type
  • va_arg
    not supported

guida alla traduzione del tipo ritornato da ccall e cfunction
For translating a C return type to Julia:

  • void
    Void (this will return the singleton instance nothing::Void)
  • T, where T is one of the primitive types: char, int, long, short, float, double, complex, enum or any of their typedef equivalents
    T, where T is an equivalent Julia Bits Type (per the table above)
    if T is an enum, the argument type should be equivalent to Cint or Cuint
    argument value will be copied (returned by-value)
  • struct T (including typedef to a struct)
    T, where T is a Julia Leaf Type
    argument value will be copied (returned by-value)
  • void*
    depends on how this parameter is used, first translate this to the intended pointer type, then determine the Julia equivalent using the remaining rules in this list
    this argument may be declared as Ptr{Void}, if it really is just an unknown pointer
  • jl_value_t*
    Any
    argument value must be a valid Julia object
  • jl_value_t**
    Ref{Any}
    argument value must be a valid Julia object (or C_NULL)
  • T*
    If the memory is already owned by Julia, or is an isbits type, and is known to be non-null:
    Ref{T}, where °T is the Julia type corresponding to T
    a return type of Ref{Any} is invalid, it should either be Any (corresponding to jl_value_t*) or Ptr{Any} (corresponding to Ptr{Any})
    C MUST NOT modify the memory returned via Ref{T} if T is an isbits type
    If the memory is owned by C:
    Ptr{T}, where T is the Julia type corresponding to T
  • (T*)(...) (e.g. a pointer to a function)
    Ptr{Void} (you may need to use cfunction() explicitly to create this pointer)

passare pointers per modificare l’input
Because C doesn’t support multiple return values, often C functions will take pointers to data that the function will modify. To accomplish this within a ccall, you need to first encapsulate the value inside an Ref{T} of the appropriate type. When you pass this Ref object as an argument, Julia will automatically pass a C pointer to the encapsulated data:

width = Ref{Cint}(0)
range = Ref{Cfloat}(0)
ccall(:foo, Void, (Ref{Cint}, Ref{Cfloat}), width, range)

Upon return, the contents of width and range can be retrieved (if they were changed by foo) by width[] and range[]; that is, they act like zero-dimensional arrays.

reference syntax speciale per ccall – deprecata
The & syntax is deprecated, use the Ref{T} argument type instead.

A prefix & is used on an argument to ccall to indicate that a pointer to a scalar argument should be passed instead of the scalar value itself (required for all Fortran function arguments, as noted above). The following example computes a dot product using a BLAS function.

function compute_dot(DX::Vector{Float64}, DY::Vector{Float64})
    @assert length(DX) == length(DY)
    n = length(DX)
    incx = incy = 1
    product = ccall((:ddot_, "libLAPACK"),
                    Float64,
                    (Ptr{Int32}, Ptr{Float64}, Ptr{Int32}, Ptr{Float64}, Ptr{Int32}),
                    &n, DX, &incx, DY, &incy)
    return product
end

The meaning of prefix & is not quite the same as in C. In particular, any changes to the referenced variables will not be visible in Julia unless the type is mutable (declared via type). However, even for immutable structs it will not cause any harm for called functions to attempt such modifications (that is, writing through the passed pointers). Moreover, & may be used with any expression, such as &0 or &f(x).

When a scalar value is passed with & as an argument of type Ptr{T}, the value will first be converted to type T.

🤢

SICP – cap. 2 – Esempio: sets come liste ordinate – 81 – esercizio

Continuo da qui, copio qui.

Exercise 2.61: Give an implementation of adjoin-set using the ordered representation. By analogy with element-of-set? show how to take advantage of the ordering to produce a procedure that requires on the average about half as many steps as with the unordered representation.

Al solito io chiamo Bill the Lizard 👽

The original implementation of adjoin-set made use of element-of-set? to check and see if the new element was already a member of the set. We no longer need to do this since we need to find the exact position in the set to insert the new element. As we scan through the set looking for the right position, we can simply return the set if we encounter the element we’re trying to place.

(define (adjoin-set x set)
  (cond ((null? set) (cons x '()))
        ((= x (car set)) set)
        ((< x (car set)) (cons x set)) 
        ((> x (car set)) (cons (car set)
                               (adjoin-set x (cdr set))))))

There are several different conditions, and we need to cover them all. First, since we’re no longer using element-of-set, we need to check to see if the set itself is null or empty. Second, if the we encounter the element we’re trying to add, we can just return the set. Next, if the element we’re adding is smaller than the first element of the set, we can simply cons the new element to the beginning of the set. Last, if the new element is greater than the first element of the set, we join the first element followed by the adjoin-set of the new element and the rest of the set.

Like element-of-set?, this implementation should only scan through half the set on average before finding the correct insertion point for the new element.

Belle anche le soluzioni di sicp-ex e Drewiki 😊

🤢

Julia – 94 – Eseguire codice C e Fortran – 4

Continuo da qui, copio qui.

Mappare tipi C in Julia (2/2)
corrispondenze tra struct e tipi
Composite types, aka struct in C or TYPE in Fortran90 (or STRUCTURE / RECORD in some variants of F77), can be mirrored in Julia by creating a struct definition with the same field layout.

When used recursively, isbits types are stored inline. All other types are stored as a pointer to the data. When mirroring a struct used by-value inside another struct in C, it is imperative that you do not attempt to manually copy the fields over, as this will not preserve the correct field alignment. Instead, declare an isbits struct type and use that instead. Unnamed structs are not possible in the translation to Julia.

Packed structs and union declarations are not supported by Julia.

You can get a near approximation of a union if you know, a priori, the field that will have the greatest size (potentially including padding). When translating your fields to Julia, declare the Julia field to be only of that type.

Arrays of parameters can be expressed with NTuple:

in C:

struct B {
    int A[3];
};
b_a_2 = B.A[2];

in Julia:

struct B
    A::NTuple{3, CInt}
end
b_a_2 = B.A[3]  # note the difference in indexing 
                # (1-based in Julia, 0-based in C)

Arrays of unknown size (C99-compliant variable length structs specified by [] or [0]) are not directly supported. Often the best way to deal with these is to deal with the byte offsets directly. For example, if a C library declared a proper string type and returned a pointer to it:

struct String {
    int strlen;
    char data[];
};

In Julia, we can access the parts independently to make a copy of that string:

str = from_c::Ptr{Void}
len = unsafe_load(Ptr{Cint}(str))
unsafe_string(str + Core.sizeof(Cint), len)

parametri del tipo
The type arguments to ccall are evaluated statically, when the method containing the ccall is defined. They therefore must take the form of a literal tuple, not a variable, and cannot reference local variables.

This may sound like a strange restriction, but remember that since C is not a dynamic language like Julia, its functions can only accept argument types with a statically-known, fixed signature.

However, while the type layout must be known statically to compute the ccall ABI, the static parameters of the function are considered to be part of this static environment. The static parameters of the function may be used as type parameters in the ccall signature, as long as they don’t affect the layout of the type. For example, f(x::T) where {T} = ccall(:valid, Ptr{T}, (Ptr{T},), x) is valid, since Ptr is always a word-size primitive type. But, g(x::T) where {T} = ccall(:notvalid, T, (T,), x) is not valid, since the type layout of T is not known statically.

valori SIMD
Note: This feature is currently implemented on 64-bit x86 and AArch64 platforms only.

If a C/C++ routine has an argument or return value that is a native SIMD type, the corresponding Julia type is a homogeneous tuple of VecElement that naturally maps to the SIMD type. Specifically:

  • The tuple must be the same size as the SIMD type. For example, a tuple representing an __m128 on x86 must have a size of 16 bytes.
  • The element type of the tuple must be an instance of VecElement{T} where T is a primitive type that is 1, 2, 4 or 8 bytes.

For instance, consider this C routine that uses AVX intrinsics:

#include 

__m256 dist( __m256 a, __m256 b ) {
    return _mm256_sqrt_ps(_mm256_add_ps(_mm256_mul_ps(a, a),
                                        _mm256_mul_ps(b, b)));
}

The following Julia code calls dist using ccall:

const m256 = NTuple{8, VecElement{Float32}}

a = m256(ntuple(i -> VecElement(sin(Float32(i))), 8))
b = m256(ntuple(i -> VecElement(cos(Float32(i))), 8))

function call_dist(a::m256, b::m256)
    ccall((:dist, "libdist"), m256, (m256, m256), a, b)
end

println(call_dist(a,b))

The host machine must have the requisite SIMD registers. For example, the code above will not work on hosts without AVX support.

Gestione della memoria
malloc/free
Memory allocation and deallocation of such objects must be handled by calls to the appropriate cleanup routines in the libraries being used, just like in any C program. Do not try to free an object received from a C library with Libc.free in Julia, as this may result in the free function being called via the wrong libc library and cause Julia to crash. The reverse (passing an object allocated in Julia to be freed by an external library) is equally invalid.

quando usare T, Ptr{T} e Ref{T}
In Julia code wrapping calls to external C routines, ordinary (non-pointer) data should be declared to be of type T inside the ccall, as they are passed by value. For C code accepting pointers, Ref{T} should generally be used for the types of input arguments, allowing the use of pointers to memory managed by either Julia or C through the implicit call to Base.cconvert(). In contrast, pointers returned by the C function called should be declared to be of output type Ptr{T}, reflecting that the memory pointed to is managed by C only. Pointers contained in C structs should be represented as fields of type Ptr{T} within the corresponding Julia struct types designed to mimic the internal structure of corresponding C structs.

In Julia code wrapping calls to external Fortran routines, all input arguments should be declared as of type Ref{T}, as Fortran passes all variables by reference. The return type should either be Void for Fortran subroutines, or a T for Fortran functions returning the type T.

🤢

cit. & loll – 65

Giovedì  gnocchi  😯 volevo dire cit. & loll; eccoli qui 😜

Pour l’éternité
::: CommitStrip

Nel nuovo ufficio la mia scrivania è assegnata a questo tizio, che faccio, cambio nome?
::: vikkio88

Wy is Twitter promoting Twitter on Twitter?
::: keleshev

E che tutto questo
::: SteffRomagnoli

Non Sequitur
::: GoComics

I wrote one in Java in 2012, and it works okay
::: lexi_lambda

I’ve realised there is almost no greater (by itself) single treasure than good documentation
::: _profan

Your job as a software engineer is not to write code
::: brandonsavage

Works on *my* machine
::: pikelet

Pythonistas are sooo spoiled
::: rdegges

You can have the project: Done On Time. Done On Budget. Done Properly
::: CodeWisdom

The evaluator, which determines the meaning of the expression is a programming language
sì 😁 SICP 💥
::: CodeWisdom

Caro JavaScript, te to a scrive ‘sta letterina
::: agilegigi

Stone-Age Mouse
::: pickover

Super Power
::: {turnoff.us}

Okay, here’s the deal. No more programming languages without a Maybe type
::: peterseibel

1997: I am *surfing* the web
::: funnylad5

And then we’ll all chuckle
::: matthew_d_green

No, I’M SORRY, you need to upgrade your technical team
::: marcelsalathe

New AI definition
::: GalaxyKate

#lisp is literally an #alien invented technology
::: sepisoad

If you discard everyone who makes a mistake
::: blockloop

destination: wrong code
::: internetofshit

Old, but still gold
::: jajaranza

how to be a wizard programmer
::: b0rk

I’ll pronounce GIF gif when
::: stuartsierra

I haven’t seen Blade Runner 2049 yet
::: ftrain

In Unix, everything is a file
::: owickstrom

Probability is a precise theory of imprecision
::: ProbFact

Inside every well-written large program
::: CodeWisdom

mood
::: daw985

An archaeological dig in the old Sun hq found a copy of the ancient scrolls of X11
::: alanc

I’ve been feeling like I’m a good programmer for about 3 days in a row now
::: lizardbill

Every language should allow interacting with the world without classic I/O
::: volothamp

steps to writing js in 2017
::: iamdevloper

Know how to learn
::: CodeWisdom

How do you do garbage collection
::: HackerHuntress

Is forgetting how to use words and only being able to speak in acronyms a prerequisite
::: doughellmann

I want a fog machine
::: LizQuilty

Better than usual
::: sempf

La Stampa: Così hacker israeliani
::: ilGatt0Pardo

Haskell – 11 – elementi fondamentali – 5

Continuo da qui, copio qui, scrollare fino a “Lists versus tuples”.

Confronto liste – tuples
As lists and tuples are often confused, let us summarise the differences between them. Tuples have the following properties:

  • Fixed size, i.e., fixed number of components: the pair (1, 2) :: (Int, Int) and the triple (1, 2, 3) :: (Int, Int, Int) have different types.
  • Components may be of different type: (5, Hello) makes perfect sense.

In contrast, the following are the properties of lists:

  • Variable size, i.e., number of components may vary: [1, 2] :: [Int] and [1, 2, 3] :: [Int] have the same types.
  • Components must be of the same type: [5, Hello] is incorrect.

Stringhe come liste
Strings are in fact a particular form of lists in Haskell, which are defined as follows in the Prelude:

type String = [Char]

Hence, list operations work on strings. "Hello" !! 1   ⇒   'e' In fact, in Haskell, "Hello" is exactly the same as ['H', 'e', 'l', 'l', 'o']. This is very convenient, as we will see that there are many powerful list processing operations and these are directly available for string manipulation.

Hence, if we ask the Haskell system for the type of an expression that produces a list, it may report the type as either String or as [Char]. As these two types have been deemed equal by the above type definition, they may be used interchangeably

Funzioni parziali
Some list functions, such as length, may be applied to any list and always produce a meaningful result. In contrast, some other functions, such as head and tail, fail for some lists. For example, if we apply head to an empty list, we get a runtime error or runtime exception.

Prelude> head []
*** Exception: Prelude.head: empty list

The function head is defined by pattern matching using the same symmetry between list construction and list pattern matching as we discussed previously for tuples — i.e., it matches on the cons-operator (:):

head :: [a] -> a
head (x:xs) = x

When head gets applied to the empty list, there is simply no function equation that matches this case. We call such functions partial functions. Their definition ignores —or is invalid for— some of the input values admitted by the function’s type signature. We discussed that types represent sets of related values; hence, partial functions are functions that are only defined for a subset of the values included in their argument types. The opposite are total functions. Total functions, such as length, are defined for all values included in the sets represented by their argument types.

Partial functions are a common source of programming mistakes. Hence, good style dictates that the documentation of a partial function (e.g., as a comment preceding the function definition) includes a statement specifying the range of admissible input values (and specifies what happens if the function is incorrectly called with an argument that is outside of this range).

The Haskell Prelude includes the function

error :: String -> a

that always results in a runtime error using its argument as the error message — that is, we have

Prelude> error "encountered a fatal error"
*** Exception: encountered a fatal error

We can use error to customise the error message of a partial function. For example, the complete definition of head in the Haskell Prelude reads as follows:

head :: [a] -> a
head (x:_) = x
head []    = error "Prelude.head: empty list"

This is better than the default error message generated by the Haskell compiler, which includes the location of the failing function definition, but doesn’t specify the argument value that led to the failure.

Note the use of the underscore _ as the second argument of the cons-operator in the first equation. It represents a pattern matching position whose value is not used in the body of the function definition. It is better style than using a regular variable name, such as xs, as it immediately signals that the corresponding value goes unused. Instead of a plain underscore, we can also use variable names starting with an underscore character (here, for example _xs) to indicate that the value is not used.

Layout
Unlike in many other programming languages, formatting matters in Haskell. In other words, the correct use of indentation and newlines is crucial to avoid errors. This allows the language to do away with some of the noise that is introduced by some other languages to disambiguate the input — in particular, Haskell programs don’t need curly braces or semicolon to delimit blocks and statements.

Compare

foo x 
  = a + b
  where
    a = 1 + x
    b = 2

to

foo x 
  = a + b
  where
    a = 1 + x
b = 2

Both are legal programs. However, in the first one, the definition of b is part of the where binding and therefore local to foo whereas in the second program, the use of b is not restricted to foo.

An example of proper layout is the function distance that we discussed earlier:

distance :: ColourPoint -> ColourPoint -> Float
distance (x1, y1, colour1) (x2, y2, colour2) 
  = sqrt (fromIntegral (dx * dx + dy * dy))
  where
    dx = x2 - x1
    dy = y2 - y1

There are three layout rules that we have to follow to get syntactically correct programs:

  • All program code that belongs to a function definition has to be further to the right than the first character of that definition (i.e., the first character of the function name). In the case of distance, all code has to be further to the right than the column in which the character d of the function name distance is located.
  • Similarly, all code of a local definition in a where clause must be further to the right than the first character of the name of the variable defined by the binding.
  • All definitions within a where clause must be aligned — e.g., above the definitions of dx and dy start in the same column.

Alternatively, we can explicitly group the bindings of a where clause using curly braces, and separate the individual bindings by semicolons:

distance (x1, y1, colour1) (x2, y2, colour2) 
  = sqrt (fromIntegral (dx * dx + dy * dy))  
  where {dx = x2 - x1; dy = y2 - y1}

Inside the curly braces, we can format the code anyway we like, because the compiler can still figure out what belongs where. Nevertheless, while the following program is legal

distance (x1, y1, colour1) (x2, y2, colour2) 
  = sqrt (fromIntegral (dx * dx + dy * dy)) where {dx 
= x2 - 
x1; dy = y2 - y1}

it is hard to read and clearly pretty bad style. Seasoned Haskell programmers who prefer explicit bracketing align the braces and the semicolons at the beginning of each line (which looks rather strange to, say, a C-programmer, who is used to having semicolons at the end of the line):

distance (x1, y1, colour1) (x2, y2, colour2) 
  = sqrt (fromIntegral (dx * dx + dy * dy))  
  where 
    { dx = x2 - x1
    ; dy = y2 - y1
    }

Qui (di là) volendo c’è il video riassuntivo.

🤢

Julia – 93 – Eseguire codice C e Fortran – 3

Continuo da qui, copio qui.

Mappare tipi C in Julia (1/2)
It is critical to exactly match the declared C type with its declaration in Julia. Inconsistencies can cause code that works correctly on one system to fail or produce indeterminate results on a different system.

Note that no C header files are used anywhere in the process of calling C functions: you are responsible for making sure that your Julia types and call signatures accurately reflect those in the C header file. (The Clang package can be used to auto-generate Julia code from a C header file.)

autoconversione
Julia automatically inserts calls to the Base.cconvert() function to convert each argument to the specified type. For example, the following call:

ccall((:foo, "libfoo"), Void, (Int32, Float64), x, y)

will behave as if the following were written:

ccall((:foo, "libfoo"), Void, (Int32, Float64),
      Base.unsafe_convert(Int32, Base.cconvert(Int32, x)),
      Base.unsafe_convert(Float64, Base.cconvert(Float64, y)))

Base.cconvert() normally just calls convert(), but can be defined to return an arbitrary new object more appropriate for passing to C. For example, this is used to convert an Array of objects (e.g. strings) to an array of pointers.

Base.unsafe_convert() handles conversion to Ptr types. It is considered unsafe because converting an object to a native pointer can hide the object from the garbage collector, causing it to be freed prematurely.

corrispondenze dei tipi
First, a review of some relevant Julia type terminology:

Syntax /   Example              Description
Keyword

mutable    String               "Leaf Type" :: A group of related data that 
struct                          includes a type-tag, is managed by the Julia GC,
                                and is defined by object-identity. The type 
                                parameters of a leaf type must be fully defined 
                                (no TypeVars are allowed) in order for the 
                                instance to be constructed.

abstract   Any,                 "Super Type" :: A super-type (not a leaf-type)
type       AbstractArray{T, N}, that cannot be instantiated, but can be used to
           Complex{T}           describe a group of types.
          
T{A}       Vector{Int}          "Type Parameter" :: A specialization of a type
                                (typically used for dispatch or storage
                                optimization).

                                "TypeVar" :: The T in the type parameter
                                declaration is referred to as a TypeVar 
                                (short for type variable).
                                
primitive  Int, Float64         "Primitive Type" :: A type with no fields, 
type                            but a size. It is stored and defined by-value.
   
struct     Pair{Int, Int}       "Struct" :: A type with all fields defined to 
                                be constant. It is defined by-value, and may 
                                be stored with a type-tag.

           Complex128           "Is-Bits" :: A primitive type, or a struct type
           (isbits)             where all fields are other isbits types. It is
                                defined by-value, and is stored without a 
                                type-tag.

struct     nothing              "Singleton" :: a Leaf Type or Struct with no 
...;                            fields. 
end

(...) or   (1, 2, 3)            "Tuple" :: an immutable data-structure similar
tuple(...)                      to an anonymous struct type, or a constant
                                array. Represented as either an array or a
                                struct.

tipi bits
There are several special types to be aware of, as no other type can be defined to behave the same:

  • Float32
    Exactly corresponds to the float type in C (or REAL*4 in Fortran).
  • Float64
    Exactly corresponds to the double type in C (or REAL*8 in Fortran).
  • Complex64
    Exactly corresponds to the complex float type in C (or COMPLEX*8 in Fortran).
  • Complex128
    Exactly corresponds to the complex double type in C (or COMPLEX*16 in Fortran).
  • Signed
    Exactly corresponds to the signed type annotation in C (or any INTEGER type in Fortran). Any Julia type that is not a subtype of Signed is assumed to be unsigned.
  • Ref{T}
    Behaves like a §§Ptr{T} that can manage its memory via the Julia GC.
  • Array{T,N}
    When an array is passed to C as a Ptr{T} argument, it is not reinterpret-cast: Julia requires that the element type of the array matches T, and the address of the first element is passed.
    Therefore, if an Array contains data in the wrong format, it will have to be explicitly converted using a call such as trunc(Int32, a).
    To pass an array A as a pointer of a different type without converting the data beforehand (for example, to pass a Float64 array to a function that operates on uninterpreted bytes), you can declare the argument as Ptr{Void}.
    If an array of eltype Ptr{T} is passed as a Ptr{Ptr{T}} argument, Base.cconvert() will attempt to first make a null-terminated copy of the array with each element replaced by its Base.cconvert() version. This allows, for example, passing an argv pointer array of type Vector{String} to an argument of type Ptr{Ptr{Cchar}}.

On all systems we currently support, basic C/C++ value types may be translated to Julia types as follows. Every C type also has a corresponding Julia type with the same name, prefixed by C. This can help for writing portable code (and remembering that an int in C is not the same as an Int in Julia).

indipendenti dal sistema

C name              Fortran      Standard     Julia Base Type
                    name         Julia Alias
                     
unsigned char       CHARACTER    Cuchar       UInt8

bool (only in C++)               Cuchar       UInt8

short               INTEGER*2,   Cshort       Int16
                    LOGICAL*2
                    
unsigned short                   Cushort      UInt16

int, BOOL (C,       INTEGER*4,   Cint         Int32
typical)            LOGICAL*4

unsigned int                     Cuint        UInt32

long long           INTEGER*8,   Clonglong    Int64
                    LOGICAL*8

unsigned long                    Culonglong   UInt64
long

intmax_t                         Cintmax_t    Int64

uintmax_t                        Cuintmax_t   UInt64

float               REAL*4       Cfloat       Float32

double              REAL*8       Cdouble      Float64

complex float       COMPLEX*8    Complex64    Complex{Float32}

complex double      COMPLEX*16   Complex128   Complex{Float64}

ptrdiff_t                        Cptrdiff_t   Int

ssize_t                          Cssize_t     Int

size_t                           Csize_t      UInt

void                                          Void

void and                                      Union{}
[[noreturn]] 
or _Noreturn

void*                                         Ptr{Void}

T* (where T                                   Ref{T}
represents an 
appropriately 
defined type)

char*               CHARACTER*N               Cstring if NUL-terminated, 
(or char[],                                   or Ptr{UInt8} if not
e.g. a string)

char**                                        Ptr{Ptr{UInt8}}
(or *char[])

jl_value_t*                                   Any
(any Julia Type)

jl_value_t**                                  Ref{Any}
(a reference to 
a Julia Type) 

va_arg                                        Not supported

... (variadic                                 T... (where T is one of the 
function                                      above types, variadic functions 
specification)                                of different argument types are
                                              not supported) 

The Cstring type is essentially a synonym for Ptr{UInt8}, except the conversion to Cstring throws an error if the Julia string contains any embedded NUL characters (which would cause the string to be silently truncated if the C routine treats NUL as the terminator). If you are passing a char* to a C routine that does not assume NUL termination (e.g. because you pass an explicit string length), or if you know for certain that your Julia string does not contain NUL and want to skip the check, you can use Ptr{UInt8} as the argument type. Cstring can also be used as the ccall return type, but in that case it obviously does not introduce any extra checks and is only meant to improve readability of the call.

dipendenti dal sistema

C name         Standard     Julia Base Type
               Julia Alias
               
char           Cchar        Int8 (x86, x86_64), UInt8 (powerpc, arm)
long           Clong        Int (UNIX), Int32 (Windows)
unsigned long  Culong       UInt (UNIX), UInt32 (Windows)
wchar_t        Cwchar_t     Int32 (UNIX), UInt16 (Windows)

Note: When calling a Fortran function, all inputs must be passed by reference, so all type correspondences above should contain an additional Ptr{..} or Ref{..} wrapper around their type specification.

Warning: For string arguments (char*) the Julia type should be Cstring (if NUL– terminated data is expected) or either Ptr{Cchar} or Ptr{UInt8} otherwise (these two pointer types have the same effect), as described above, not String. Similarly, for array arguments (T[] or T*), the Julia type should again be Ptr{T}, not Vector{T}.

Warning: Julia’s Char type is 32 bits, which is not the same as the wide character type (wchar_t or wint_t) on all platforms.

Warning: A return type of Union{} means the function will not return i.e. C++11 [[noreturn]] or C11 _Noreturn (e.g. jl_throw or longjmp). Do not use this for functions that return no value (void) but do return, use Void instead.

Note: For wchar_t* arguments, the Julia type should be Cwstring (if the C routine expects a NUL-terminated string) or Ptr{Cwchar_t} otherwise. Note also that UTF-8 string data in Julia is internally NUL-terminated, so it can be passed to C functions expecting NUL-terminated data without making a copy (but using the Cwstring type will cause an error to be thrown if the string itself contains NUL characters).

Note: C functions that take an argument of the type char** can be called by using a Ptr{Ptr{UInt8}} type within Julia. For example, C functions of the form:

int main(int argc, char **argv);

can be called via the following Julia code:

argv = [ "a.out", "arg1", "arg2" ]
ccall(:main, Int32, (Int32, Ptr{Ptr{UInt8}}), length(argv), argv)

Note: A C function declared to return Void will return the value nothing in Julia.

Panico 😊 e continua.

🤢