GolfScriptの改良バージョン[終了]


12

私は、もっと多くのことができるより短いプログラムのために、改善されたGolfScriptを書くつもりです。これは挑戦ではありません。それは私がすべきことについてのフィードバックとヒントのリクエストです。(タグを参照)

これがコミュニティWikiかどうかはわかりません。もしそうだと思うなら、モデレーターにそれを変換するようにフラグを立ててください:)

この言語は、GolfScriptと非常によく似ています。まだRubyで書かれています。ただし、いくつかの違いがあります。

  • `文字列の区切り文字として使用します。これは一般的な文字ではないため、エスケープの必要は少なくなります。(他のキャラクターは、その機能を置き換えることができます#(詳細は後ほど))。\`バックティック\\をエスケープする、バックスラッシュをエスケープする、他のエスケープシーケンスはありません。改行が必要な場合は、文字列に実際のリテラル改行を挿入するだけです。
  • RationalGolfScriptの主な欠陥の1つである任意精度の浮動小数点にRubyを使用する。
  • 型を他の型に変換する機能。たとえば、ブロックを文字列に変換できます。
  • 正規表現。おそらくで作成されました"..."。オペレーターもそれらに対して過負荷になります。たとえば、"\W"~{`Invalid: non-word character`}{`OK`}if。ブロックなどの変数からプッシュされると、自動的に実行されます。
  • ファイルおよび日付オブジェクト。GolfScriptでは不可能だったより多くのことを行います。これらにはリテラルはありませんが、それらを初期化するための関数`file.txt`flがあります(ファイル作成関数の名前は変更される場合があります)。
  • ハッシュかもしれませんが、それについてはわかりません。したほうがいい?
  • さらに機能するヘルパー関数。たとえば、`http://example.com`netネットワークアクセスの場合(ここでも、net演算子の名前を変更できます)。rb文字列をRubyコードとして実行します。これらはさらに多くあります。提案を歓迎します。
  • コメントはありませんので、#他のことに使用できます。コメントが必要な場合は、問題`comment here`;なく機能します。(おそらく関数#を置き換えることができ`ます)
  • 関数を追加するのがはるかに簡単になるように完全に書き直されます。基本的に、コードはより読みやすくなります。(GolfScriptのソースを見ましたか?:/
  • Github上にあるため、共同で作業できます。私はMITか何かの下でそれを認可します。
  • 最終的な改行がないため、チートなクインが機能します:P

そして、私はこれらを最も劇的で有用な変更だと思うので、これらを区別しています(おそらく浮動小数点を追加することを除く):

  • 多くのRuby関数が組み込まれています。例えば、shuffle(略称されてもよいsf)(以前にかかった9文字)、 tr(以前は14文字)、 samplesm予め.,rand=)、 flattenfl以前???)、等
  • レブムのようにドロドロになります。たとえば~:a0<{0a-}aIF~:$0<{0$-}$if(sort関数を上書きする)代わりに(文字変数名を使用して)できるようになりました。(ここからの例)。この方法では、大文字と小文字が区別されず、変数名に数字を使用できないことに注意してください。これはゴルフの言語なので、私の意見では大丈夫です:P
  • デバッグが行われます。配列区切り文字、要素区切り文字などを指定するフラグ、数値出力(有理数、浮動小数点数、または整数?)、命令を1つずつステップ実行し、プログラムを実行する代わりに各トークンをトークン化して出力する機能を追加します。等

だから、私の質問は次のとおりです。改善するものは何ですか?何を追加すべきだと思いますか?

コーディングを始める前に、これに関する他のアイデアはありますか?


ミュージングを追加すると、大文字と小文字の区別が失われることに注意してください。
マリヌス

@marinus私はそれを理解しています。私はそれを明確にすべきでした。編集...
ドアノブ

また、本当に必要なのは、明示的なI / Oを行う方法です(対話型プログラムの場合)。インタープリターは、プログラムが明示的なI / Oを使用しているかどうかを事前に確認し、使用していない場合にのみ暗黙的なI / Oを実行できます。
マリヌス

@marinus素晴らしい、それを答えとして追加する必要があります:)
Doorknob

1
@Claudiu新しい言語での私の開発は非常に活発ですが、最近はかなり忙しいので、しばらくはあまり使いませんでした。これらのアイデアのいくつかは、ただ良いアイデアではありませんが、私は使用していません:P
ドアノブ

回答:


17

柔軟なI / O

現時点では、Golfscriptをインタラクティブプログラムに使用することはできません。明示的な入力のためのいくつかの関数を追加することを提案します(つまりreadlinegetchar友人)。インタープリターは、実行前にプログラムがこれらを使用するかどうかを確認する必要があります。

プログラムが入力関数を呼び出さない場合、インタープリターはGolfscriptが通常行うように動作する必要があります。

インタプリタが実行時に生成された評価済みコードの入力関数を検出することは期待していませんが、それが何らかの形でそれを行うことができるなら、称賛に値します。


これは素晴らしいアイデアです。ioの制限は、golfscriptの大きな制限の1つです。+1
ドアノブ

11

より短いビルトイン

それらを持たないすべての組み込みコマンドの単一文字エイリアス。baseそれがちょうどだったら私はもっともっと使うだろうB


しかしb、変数名として使用するとどうなりますか?それでも; 良いアイデア; 関数を使用する場合はその名前を使用しないことを忘れないでください。関数を使用しない場合は、まったく影響しません。
ドアノブ

@DoorknobofSnow、すでにビルトインを使用することができます(とさえなどのトークン^または$)変数名として。その問題が悪化することはありません。さらに、下位互換性を可能にするエイリアスを提案したので、短いエイリアスに別の何かを割り当てた場合は、長い名前を使用する必要があります。
ピーターテイラー

4
Z以下のためにzipも非常に有用であろう。
ハワード

GolfScriptの公式標準ライブラリをリリースできるかもしれません。しかし、私はそれがソリューションにどのように含まれるかについては不明です(欠落して#includeおり、"#{IO.read'lib'}"~長すぎます)。
ハワード14年

@Howardこれがアイデアです...多分のように、自分の言語にライブラリを追加できますmylang -Llibname somefile.ext
ドアノブ

9

div-modの組み合わせ

これは、提案のいくつかよりも少しニッチですが、数論のプログラムに取り組んでいたとき、私は頻繁に自分自身が2つの整数をポップ操作たく見つけるab、スタックとプッシュからa/bとしますa%b。(現在、これは1$1$/@@%)です。


それはとてもニッチなのでdvm、DiV-Modのようなものかもしれません。すべてのアイデアをありがとう:-) +1
ドアノブ

8

数字

先行0が数値の一部ではないようにレクサーを変更します。

# current behaviour
01     # -> 1

# new
01     # -> 0 1

また、_代わりに負の数を記述する必要があります。

# current behaviour
1 2-3   # -> -1 3

# new
1 2_3     # -> 1 2 -3

おもしろいですね。通常、2つの数字を連続してプッシュすることは通常ありませんが、これは非常に役立ちます。0 100-マイナス100の代わりに、マイナスも素晴らしいです。+1
ドアノブ

1
私はこれについて前に考えました。負の整数リテラルのサポートは一切ありません。で既に処理されてい~ます。たとえば、-1は0~です。これにより、少数の数字が1文字分長くなりますが、後に頻繁に頻繁に発生する空白は不要になります-
ピーターテイラー

ちょっと待って、たとえば1001をプッシュしますか?後続ではなく、先行ゼロを意味したと思います。
ドアノブ

@DoorknobofSnowそうですね。
ハワード

あなたは何をして{0\-}:~;~数字を負にした)、notビットごとに(ちょうどのようにand or xor)使用することについてどう思いますか?
ドアノブ

8

スタック全体へのアクセス

GolfScriptはスタックベースの言語ですが、スタックの上位3つのアイテム以外のすべてへのアクセスは<integer>$、n番目のアイテムのコピーに制限されています。PostScriptのrollコマンドのようなものを用意しておくと、3つ以上の「ライブ」変数で作業しやすくなります。

理想的には、1引数バージョンと2引数バージョンがありますが、周囲に十分な名前がない場合は、1引数は1文字のものに優先されるはずです。

引数が1つの場合は、ロールするアイテムの数だけを取ります。たとえば、1 roll何もしません。2 rollに等しい\; 3 rollに等しい@; 4 rollそして、より大きな数字には既存の同等物がありません。可能な限り最も近いものは

]-4/()\+\+[]*-1%~

(そして、それはスタック上の特定の位置、またはactive [で非整数さえも処理せず、ほぼ確実にループ内で壊れます)。

引数が2つの場合も、ロールするのにある程度の時間がかかります。a b roll2はと同等{a roll}b*です。


だから、Rubyのようにrotate。これをCWの回答に編集する必要があります。
ドアノブ

@Doorknob、いいえ。私はアレイではなく、スタックのスライスで操作することについて話している。
ピーターテイラー14年

うーん...あなたが何を意味するのか分かりません。私はポストスクリプトに精通していませんがroll、配列を回転させるだけですよね?
ドアノブ

@DoorknobofSnow、スタック。配列は、スタック上にあるアイテムです。
ピーターテイラー

ああ、それでスタック全体を回転させます。ああ、それは役に立つかもしれません!+1
ドアノブ

8

CJam

「改良されたGolfScript」を実装しました。これはCJamと呼ばれます-http : //sf.net/p/cjam
現在、2番目のリリース(バージョン0.6)では、ここで説明する機能のほとんどではなくとも多くを既に備えています。それらをリストしてみます:

  • まだRubyで書かれている-いや、Java
  • `文字列の区切り文字として使用-いいえ、ただし、エスケープが最小限の二重引用符付き文字列を使用します(\エスケープのみ\および"
  • 浮動小数点-サポートされていますが、任意の精度ではなく標準の「double」のみ
  • タイプを他のタイプに変換-はい
  • 正規表現-まだではありませんが、計画中です。特別な演算子で通常の文字列を使用します
  • ファイルおよび日付オブジェクト-いいえ、ただし現在の日付/時刻を取得できます
  • ハッシュ-それらがpython dictまたはjavaマップのようなものであると仮定すると、それらはサポートされません(将来検討される可能性があります)
  • さらに多くのことを行うヘルパー関数-はい、たくさん
  • `http://example.com`net - "example.com"g
  • Rubyコードとして文字列を実行する-いいえ
  • コメントなし-正確に、#他の何かに使用され、"comments like this";
  • 関数を追加するのが簡単です-そうだと思いますが、私もバイアスがかかっています:)
  • Githubで-さらに良い(私の意見では、撮影しないでください)-SourceForgeでhgを使用して
  • MITでライセンスされています-はい
  • 最終改行なし-右
  • シャッフル- mr
  • tr- er
  • サンプル-未完了、 _,mr=
  • 平坦化-完了していませんが、おそらく簡単に達成できます
  • マッシュ-いいえ、しかし識別子は分離する必要はありません
  • デバッグ-スタックトレースのみ、およびedスタックを表示するための演算子

  • 柔軟なI / O-はい、ただし明示的な入力のみ

  • 短いビルトイン-はい、b=ベース、z= zip
  • 先行する0を分けます-いいえ、ただし定義済みの変数を使用できます
  • 明確に--はい、しかしではないと_1 2-3-> 1 2 -3; 1 2m3->-1 3
  • スタックのロール/回転-いいえ
  • 配列セット- t
  • divmod- md
  • レクサーを変更する(識別子用)-はい、詳細は以下
  • デカルト積-まったく同じではありませんが、はい、 m*
  • ユニコード演算子-いいえ
  • 単一文字の識別子-定義済みの演算子には1文字または2文字があり、変数は単一文字の大文字です。それらはすべて、レクサー/パーサーを混乱させることなく連結できます。
  • ブロック上の演算子-いいえ
  • 安定したソート-はい
  • シンボルをコードブロックに戻します-いいえ、ただし後で追加できます
  • 現在の日付/時刻- et
  • コマンドライン引数- ea
  • ビルトインを明確に分離-はい、ただし大文字は変数です。組み込みは、小文字および特殊文字で始まります
  • minおよびmax-はい、現在2つの値のみ:e<e>
  • 絶対値- z(GolfScript absには欠けていないがあります)
  • 配列の和と積- :+:*
  • マンハッタン距離-いいえ
  • chr- c(文字列ではなく文字に変換します)
  • 文字列をスタックにこぼします-CJam文字列は数字ではなく文字で構成されています。キャラクターをこぼすにはまだ{}/
  • :保存されているものを消費するバージョン-いいえ
  • 事業者にとって>=<=-いや、使用<!>!
  • base64およびzlib-いいえ
  • 1 $、2 $、3 $、4 $、5 $のショートカット-いいえ
  • 上位2つのスタックアイテムをコピーします-計画済み。今のところ使用1$1$
  • ローカル変数-いいえ
  • HQ9 +の機能-いいえ、ありがとう

CJamにはさらに多くの機能があります。https: //sourceforge.net/p/cjam/wiki/Operators/をご覧ください


7
SourceForgeとMercurialがGitHubより優れていることに同意しません。
nyuszika7h 14年

1
nyuszika7h @それは大丈夫、我々はすべて私たちの好みを持っているのです
SEは悪であるため、aditsuは終了

GolfScriptの答えには適切なsqrt関数が必要だったため、最初のCJamの答えを投稿しました。CJamはGolfScriptよりもはるかに高速です!
デニス


@aditsu Would you consider CJam a dialect of GolfScript or a new language inspired by GolfScript? (Here's the reason I'm asking: codegolf.stackexchange.com/questions/37464/…)
Martin Ender

6

Change the lexer

GolfScript's lexer treats a Ruby identifier (anything which matches the regex [_a-zA-Z][_a-zA-Z0-9]*) as a single token. If it instead treated [a-zA-Z]+ as a token that would free up _ to be a built-in and would allow an alpha variable to be followed by a literal integer without separating whitespace.


Well, currently I'm using simply [a-z]+|[A-Z]+, for the mushing, so underscore is free. This is an interesting and very unique idea though! +1
Doorknob

5

Unicode aliases

Multiple-character commands could have unicode aliases. This would save on the score when the score is counted in characters and not in bytes.


7
uh... we don't want another APL...
John Dvorak

1
Golfscript isn't anything like APL, Unicode or no. We already have several other APLs, like J and K. (or even R which looks quite APL-inspired to me, to the point that you can do literal translations quite often)
marinus

The distinguishing point about APL is that it uses a very different charset than anything else, not that it uses vector arithmetic natively. I like J, I use it, and I commonly upvote J answers. I've yet to upvote one APL answer. If I wanted to paint my programs instead of writing them, I'd use Piet.
John Dvorak

I think APL is more legible than J, certainly more legible than Golfscript.
marinus


5

Array set operator

["A" "B" "C" "D" "E" "F"] -1 4 S    # -> ["A" "B" "C" "D" -1 "F"]

Any built-in we can make available for that?


+1 I started writing a blog post about implementing array set, but never finished it. It's currently extremely hard in full generality. This would make a big difference to some challenges.
Peter Taylor

I can't believe this isn't built in to golfscript already. +1
Doorknob

5

Single-character identifiers

It's not like a code golf solution is going to have too many variables. And it would save on spaces.


Hmm.. This could also be done by changing the parser. Perhaps a flag to specify this behavior? Great idea! +1
Doorknob

4

% as builtin for product

[1 2][1 2 3]%  # -> [[[1 1][1 2][1 3]][[2 1][2 2][2 3]]]

+1; you could edit my CW answer and add this one
Doorknob

What about modulo?
MilkyWay90

3

Regex support

The lack of regex support has always struck me as odd in a language designed for golfing. It would be great to have

  • <string> <string> <string> y (aka tr, using Perl's one-char alias for it)
  • <string> <string> <string> s (substitute)
  • <string> <string> <block> s (substitute with callback)
  • <string> <string> m (match)

I already mentioned regex in my question.
Doorknob


3

Make |, & and ^ built-ins do something useful on blocks

E.g. <array/string> <block> | can be used as index function

[0 -10 -20 30 40 -50 60] {0<} |   # -> [1 2 5]

Any ideas for <array/string> <block> & or <array/string> <block> ^?


What does array block = do now?
John Dvorak

@JanDvorak Compare. Useful if you want to compare a string to a block, e.g. "0<" {0<} =.
Howard

How often do you need that? I'd rather drop that, and use array block = for "select by predicate"
John Dvorak

@JanDvorak select by predicate is already implemented using ,.
Howard

oh, never mind. Go on :-)
John Dvorak

2

A way to turn symbols back into code blocks

Currently, we can bind code blocks to symbols with :, but there's no way to reverse the process: executing a symbol bound to a code block just executes the block.

I can see a couple of ways to implement this:

  1. add new syntax, e.g. #foo to push the value of foo to the stack, even if it's a code block, or

  2. add an operator to expand every symbol in a code block, so that (using _ as the new operator), e.g. {2*}:dbl; {dbl dbl}_ would produce {2* 2*}.

I can see advantages to both methods. The latter could substitute for the former, at the cost of two extra chars ({foo}_ instead of #foo), but I can see some potential applications for the former syntax where those two chars would be prohibitive (e.g. using array #func % instead of array {func} %).

Meanwhile, the former syntax could be used to replace the latter if there was a convenient way to somehow iterate over the tokens in a code block (which could be useful on its own, anyway).


In either case, I'd propose that expanding symbols that are bound to native built-ins (i.e. implemented in Ruby code) should return some kind of stub that could be called to obtain the functionality of the built-in, while being either impossible or just unlikely to be overridden. For example #$ (or {$}_) could return e.g. {builtin_dollar}, where builtin_dollar would contain the actual implementation of the $ built-in (and #builtin_dollar or {builtin_dollar}_ should just return {builtin_dollar} itself).

This would allow built-ins to be redefined without losing access to their functionality (see my earlier suggestion), so that if I, say, for some reason wanted to swap the meanings of $ and @, I could just do #$ #@ :$; :@; (or {$}_ {@}_ :$; :@;).


One detail I'm not sure of is what the _ operator should do if the code block contains variable assignments. The obvious thing would be to just leave any :symbol tokens untouched and expand anything else, but this would cause _ to break any code using local variables. Making it not break such code might be impractically complicated, though.
Ilmari Karonen

1
Your second version would fit together with an flatten operator on arrays: [[1] [2] [3]] _ -> [1 2 3].
Howard

So what would be the result of 2:A;{1:A;A}_?
Howard

Naïvely, {1:A;2} (or, to be technical, {1:A builtin_semicolon 2} if the built-in expansion feature was included). If some kind of "local variable exclusion" feature was included, it might plausibly evaluate to just {1:A;A}.
Ilmari Karonen

Or to be even more technical {builtin_1 :A builtin_semicolon 2}.
Howard

1

Variable preset with command line args

Unfortunately, there isn't any char left unassigned, but maybe we can use A for that?


_ is available. Perhaps that? Anyway, yes, golfscript needs a way of taking cmd line args +1
Doorknob

0

Native Ruby functions that I should implement

This is Community Wiki; feel free to edit and add the functions you think I should implement!

Format: "nativeFunctionName (nameInMyLanguage)"

  • shuffle (sf)
  • tr (tr)
  • sample (sm)

0

Take features from APL and HQ9+ too!

  • Shortcuts, like in APL. EDIT: just saw the answer "unicode aliases". That's what I meant :)
  • Other golf-oriented shortcuts, like in H9+, HQ9+, CHIQRSX9+

Okay, so how would you propose that? Any specific ideas?
Doorknob

unicode characters allowing to do complex things in just one character.
xem

@Doorknob of Snow , I updated my answer with the shortcuts I'd like to see: those from APL, and those from CHIRQSX9+ :)
xem

Hmm, the hq9+ thing seems too cheaty :-P
Doorknob

It's golf oriented :P im my opinion your language should do at least as well :)
xem

0

Clearly separating built-ins

e.g. capitals : built-ins ; making B for base feasable


1
As mentioned above there is no need to separate. If someone likes to overwrite a builtin he should be able to do so. I even found useful applications of overwriting operators like {-}:+.
Howard

No need, also this language will be case insensitive.
Doorknob

2
Since the goal is to provide less strokes per hole, having case sensitivity and more built-ins effectively leads towards the mission statement.

0

Local variables / closures

One thing I really miss in GolfScript is the ability to temporarily change the value of a symbol.

In particular, there's currently no way to temporarily override the meaning of a "primitive" built-in: once you, say, redefine $, you're never going to sort anything in that program again. (Well, not without writing your own sort implementation, at least.) It would be really nice to be able to say, for example, that in this code block $ means something else, but still keep the normal meaning elsewhere.

Related to the above, it would be nice to bind symbols in a code block to their current value. Sure, I can write, say, {$-1%}:rsort and be able to use rsort to sort and reverse an array, but that works only as long as the definition of $ (or -1 or %) doesn't change, since my rsort function is still calling the global symbol $. It would be nice to be able to say "let rsort do what $-1% currently does, even if those symbols are later redefined."

In particular, the standard library could use this kind of binding. It's kind of surprising to realize that, say, changing n changes the behavior of puts, or that redefining ! completely messes up xor. (Then again, some caution should be exercised here, since, in particular, the ability to change the behavior of puts turns out to be turns out to be the only way to avoid printing a final newline in the current version of GS.)

Edit: Being able to turn symbols back into code blocks would go a long way towards implementing this functionality. In particular, the {foo}_ syntax suggested in that answer would effectively perform one level of static binding by expanding all symbols in a code block. Combine that with a fixpoint combinator for deep static binding, and Bob's your uncle...


Come on - all the fancy new languages celebrate lazy evaluation ;-) Let's keep that feature in GolfScript.
Howard

On second thought - you're right, it is more a feature of binding than evaluation. But then - static binding is more complex than it sounds - e.g. provide recursive calls inside a definition.
Howard

"let rsort do what $-1% currently does, even if those symbols are later redefined" So Emmental?
CalculatorFeline

0

More built-in functions

Make all the single-letter variables a-z and A-Z perform some generic, useful function. Some built-ins that are lacking:

  • min and max: all or some of top 2 stack values, top n stack values, over an array
  • absolute value
  • sum and product of an array. why do {+}* when you can do S? You have 52 functions to work with here!
  • Manhattan distance (i.e. x1 y1 x2 y2 --> abs(x2-x1)+abs(y2-y1). Now it'd have to be @-A@@-A+ if A is a built-in absolute value. Granted this only came up caues of my most recent post but I always figured that'd be a good way to expand golfscript: write down what functions would be handy to have, collect them, and add them as built-ins.
  • Convert an integer to a one-character string (equivalent of python's chr).
  • Spill a string onto the stack (currently {}/)
  • A version of : that consumes what is stored. This would have to not get 'stuck' to identifiers to be useful.
  • Operators for >=, <=
  • As someone suggested, a way to put a variable containing a block onto the stack without executing it. So you could reduce ifs of the form 1{\}{|}if to something like 1?\?|if
  • Built-in base64 conversion and zlib support to make embedding data take less characters
  • Beyond base64, make a custom base93 encoding (using all printable characters that aren't the string delimiter).
  • Shortcuts for 1$, 2$, 3$, 4$, 5$
  • An operator to copy the top two stack items as they are, i.e. \.@.@\

-3

It'd be nice if the value written or computed in the last line of a function was automatically returned


3
It's stack-based, so...
marinus

1
There's no such thing as a function.
Peter Taylor

Functions don't return anything... and they're called blocks
Doorknob

That might be nice...in some other language. (No more annoying return statements at the end of functions! Yay! (But I haven't needed return statements ever, so...))
CalculatorFeline
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.