2011-01-14 14 views
0

私は現在、DrRacketのラケットスキームをいくつかの探索的プログラミングのエディタとして使用しています。私が試してみて、機能を再定義するとき、私は次のメッセージが出ます:今ラケットスキームの定数の再定義

define-values: cannot re-define a constant: png->byte-list 

を、私は、これは言語の財産であり、それによってイライラが、一種のそれを受け入れたことを受け入れるために使用されます。 How can you re-define a constant identifier in DrScheme?を読むと、必ずしもこの制限を受け入れる必要はありません。

次のように私の質問は以下のとおりです。

  1. はR5RS言語でのみ利用でき、この機能ですか?任意の言語に対してこの機能をオフに切り替える方法はありますか?
  2. また、R5RSの言語を切り替えると、私は現時点で使用しているモジュールracket/gui/baseとweb-server/instaを使用して私に影響を与えますか?

答えて

4

このような再定義は、定義ウィンドウで行うと#lang racketで可能です。

#lang racket 
(define orig-+ +) 
(define + whatever) 

orig-+実際の加算機能にバインドされていません。心に留めておくべき事はこれは、これは例えば、ない(R5RSの実装と共通である)突然変異の一種であるということです。このモジュールがコンパイルされると、ラケットは(静的に)+があなたが定義するものであることを知っているので、それへの参照はあなた自身の定義への参照であるため、orig-++の "未初期化"の値にバインドします。 - 別の問題である

その上で
#lang racket 
(require (rename-in racket [+ orig-+])) 
(define + whatever) 

、モジュールがコンパイルされたときに起こるインライン化があります:あなたは本当にそのような何かをしたい場合は、別の名前で元+を必要とすることができます。 Racketは通常、コード内で変異していないバインディングへの参照をインライン展開したいので、最後のコードを試しても、REPL上で+をさらに再定義することはできません。 2つの方法のうちの1つで対処できます。最初は、バインディングを明示的に変更することです。コンパイラはインライン展開を回避します。もう1つのオプションはDrRacketフラグで、すべてのインライン展開を避けるコンパイラフラグをオンにします。これに対してスピードのペナルティが大きいことに注意してください。

+0

の値を持つ「掛け算」という名前の変数DrRacketフラグは、R5RS言語のフラグを意味しますか? –

+1

はい - drracketに '#lang'というフラグがありません。混乱して申し訳ありません。 (実際は、フラグはそこにありますが、インターフェイスには公開されていません)。 –

0

1 - 私はSchemeではプロではありませんが、私はちょうど乗算関数(*)を再定義しようとしました。 「初期バインディングの再定義を禁止する」とは機能しません。しかし未確認の場合 - それは動作します:

Welcome to DrRacket, version 5.0.2 [3m]. 
Language: R5RS [custom]; memory limit: 128 MB. 
> (* 2 2) 
4 
> (define (* a b) a) 
> (* 2 2) 
2 
> 

しかし、私はあなたのエラーを取得することができませんでした私は、既存の機能を再定義した場合(定義値:...:定数を再定義することはできません) を

2 - モジュールに明示的に言語を指定する#langディレクティブがあると、問題ではないはずです(私は推測します)。

0

ここで乗算を定義する方法を示します。

(乗算*を定義します)。 *