Compatibility of typed/racket and SRFI-42

What is 'lifting'?
Are you proposing that i put untyped pieces of a function into nested submodules? Can submodules have their own languages?
Or am I completely off-track>

My assumptions were wrong. Sorry with-types doesn't work the way I expected.

It turns out that internal modules can specify the language they are written in, as exeplified in section 6.3 of https://download.racket-lang.org/releases/8.10/pdf-doc/ts-guide.pdf
Maybe something is possible!
I will have to experiment.

But I still don't know what you mean with 'lifting'.

-- hendrik

i can not find a way to use with-type, used in a TR module it is useless and in normal racket module it is undefined.

Anyway i hoped typing could bring some optimisation but it is barely the case in scheme. Even with typing scheme is fundamentally slower in my opinion than Java, C, Javascript etc .

this is out of topic here but i think that Scheme ,being based on lambda calculus, which is based on rewriting rules, this allow some easyness to write an implementation but the result is not fast. For the reason based on lambda calculus there is a lot of Scheme implementations ,perheaps 10 to 20, which is not the case of other language, for example Haskell has only one compiler maintained, C, there is GNU C ,Intel C compiler and few other only.
Even the scheme implementation that generate C code are slow, the fastest scheme implementation are not even faster than Python in a lot of case.

I suppose also Python and Scheme too are slow because the type must be find at runtime, i have also this problem in scheme+ i devellop but this is not a problem for common applications.

I think you should require with-type from typed-racket. When I do this, the examples from 10 Typed Regions work for me:

#lang racket

(require typed/racket)

(with-type #:result Number 3)

#;
((with-type #:result (Number -> Number)
   (lambda: ([x : Number]) (add1 x)))
 #f) ; ERROR: Contract violation.

(let ([x "hello"])
    (with-type #:result String
      #:freevars ([x String])
      (string-append x ", world")))

Note that the language of this module is still (untyped) Racket, as imposed by the #lang declaration in the first line.

You may want to only require typed/racket/base or use only-in to not bring in the entire Typed Racket.

Thanks.It works, i will make some test with it.

i can do that little use but it does not change speed of the code:

#lang reader "../Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/src/SRFI-105.rkt"

(provide (all-defined-out)) 

(require srfi/42) ; Eager Comprehensions

(require (prefix-in TR: typed/racket))

(require "../Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/Scheme+.rkt")

(TR:with-type ([σ (TR:Float TR:-> TR:Float)]
	       [der_σ (TR:Float TR:Float  TR:-> TR:Float)])
	       ;;[* (TR:Float TR:Float  TR:-> TR:Float)])
	       
		; sigmoïde
		(define (σ z̃) 
   			{1 / {1 + (exp (- z̃))}})

		(define (der_σ z z̃)
    			{z * {1 - z}}))


note: i prefix with TR: because without there is conflict between TR and racket definitions (example : do ) or with my code ( example : ->)

problem i have now is this error:

*: undefined;
cannot reference an identifier before its definition

in:

(require "matrix-by-vectors.rkt") ;; this file overload the * operator



(TR:with-type ([σ (TR:Float TR:-> TR:Float)]
	       [der_σ (TR:Float TR:Float  TR:-> TR:Float)]
	       [* (TR:Float TR:Float  TR:-> TR:Float)])


	       
		; sigmoïde
		(define (σ z̃) 
   			{1 / {1 + (exp (- z̃))}})

		(define (der_σ z z̃)
    			{z * {1 - z}}))

1, The name of * inside of typed/racket fragments is TR:*.

  1. If you write a simplified version of this program, like this,
#lang racket

(require (prefix-in TR: typed/racket))

(TR:with-type ([TR:* (TR:Float TR:Float  TR:-> TR:Float)])
              0)

the error message clarifies that your program is assigning an existing function a type that differs from its existing type.

  1. If you really want something like this, you may wish to write
#lang racket

(require (prefix-in TR: typed/racket))

(TR:with-type ([* (TR:Float TR:Float  TR:-> TR:Float)])
              (define (* x y) (TR:* x y)))

Yes, frequent crossings of a typed–untyped boundary will not speed up your code, and may in fact slow it down!

When you call a typed (-> Float Float) function from untyped code, Typed Racket must wrap the function to check that the argument satisfies flonum? and report an error otherwise. This wrapping is done using the contract system to provide good error messages and accurate blame information.

The code you wrote mixes the exact integer 1 with floating-point numbers. Typed Racket cannot specialize arithmetic operators with mixed-precision arguments: it must call exactly the same / and + you use in untyped Racket.

Even if you wrote 1.0, the cost of the wrapper may well exceed the benefit of Typed Racket's being able to compile (* z (- 1.0 z)) to (unsafe-fl* z (unsafe-fl- 1.0 z)). Effectively using Typed Racket for performance requires thinking carefully about the costs of typed–untyped boundary crossings.

If your primary interest is floating-point performance, you may want to consider using the operators from 4.3.3 Flonums. Even in untyped Racket, if you write (fl* z (fl- 1.0 z)) (n.b. not unsafe), the compiler will be able to locally unbox the flonums and eliminate many redundant checks.

(I don't mean to discourage you from using Typed Racket, and it can definitely be used to write ergonomic and performant numeric code: it is used by the Math Library, for example. But it is important to think through what the benefit is you are hoping to get from Typed Racket and to evaluate whether or not it is a good fit for your use-case.)

2 Likes

yes i was annoyed by the duplicate types between typed/racket and some definitions of Scheme+ or other modules (i still have the problem with *) i now use this method that allow code more readable:

#lang reader "../Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/src/SRFI-105.rkt" ; SRFI-105 Curly-infix-expressions and a few more

(provide (all-defined-out)) 

;; return a number in ]-1,1[
;;(define (uniform-dummy dummy1 dummy2) {(random) * (if {(random 2) = 0} 1 -1)})  ; we randomly choose the sign of the random number
(define (uniform-dummy dummy1 dummy2) {-1 + (random) * 2}) 


; return a random number between [inf, sup]
(define (uniform-interval inf sup)
  {gap <+ sup - inf}
  {inf + gap * (random)})


(require (rename-in typed/racket
		    (: TR:)
		    (do TR:do)
		    (unless TR:unless)
		    (for TR:for)))
		   
(with-type ([σ (Float -> Float)]
	    [der_σ (Float Float  -> Float)])
	  
		; sigmoïde
		(define (σ z̃) 
   			{1 / {1 + (exp (- z̃))}})

		(define (der_σ z z̃)
    			{z * {1 - z}}))



(require "../Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/Scheme+.rkt")

(require srfi/42) ; Eager Comprehensions



this part of code works when put in this strict order but if i add :

(require "matrix-by-vectors+.rkt")

at the end of code it fails , this add an overload definition for * which is like redefining *

i got this error then:

 module: identifier already required
  also provided by: typed/racket in: *

in fact,even the code above , pass the parsing and compilation stage but fails at execution:

Welcome to DrRacket, version 8.11 [cs].
Language: reader "../Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/src/SRFI-105.rkt", with debugging; memory limit: 8192 MB.
SRFI-105 Curly Infix parser with optimization by Damien MATTEI
(based on code from David A. Wheeler and Alan Manuel K. Gloria.)

Options :

Infix optimizer is ON.
Infix optimizer on sliced containers is ON.

Parsed curly infix code result = 

(provide (all-defined-out))
(define (uniform-dummy dummy1 dummy2) (+ -1 (* (random) 2)))
(define (uniform-interval inf sup) (<+ gap (- sup inf)) (+ inf (* gap (random))))
(require (rename-in typed/racket (: TR:) (do TR:do) (unless TR:unless) (for TR:for)))
(with-type ((σ (Float -> Float)) (der_σ (Float Float -> Float))) (define (σ z̃) (/ 1 (+ 1 (exp (- z̃))))) (define (der_σ z z̃) (* z (- 1 z))))
(require "../Scheme-PLUS-for-Racket/main/Scheme-PLUS-for-Racket/Scheme+.rkt")
(require srfi/42)
#<eof>


> (der_σ 0.2 0.5)
. Type Checker: missing type for identifier;
 consider using `require/typed' to import it
  identifier: der_σ
  from module: /Users/mattei/AI_Deep_Learning/exo_retropropagationNhidden_layers_matrix_v2_by_vectors_typed_racket+.rkt in: der_σ
> 

i understand all that. I'm just making test.

Anyway, i prefer using slower untyped language as scheme or python or javascript instead of C,C++,Java.