let 代金 = 個数*単価 // 順番が逆なので🙅 #義務教育化されたプログラミングの授業風景
— Dan Kogai (@dankogai) 2014, 6月 12
@dankogai そもそも回答が左に来ているのは間違い。
個数*単価 = 代金 Q.E.D.
という文法のプログラミング言語を作る所から始める。
— AXION (@AXION_CAVOK) 2014, 6月 12
ワシの知るかぎり、主な算譜言語で右辺値に代入できるのは R の -> だけだなあ( <- もある)。<@AXION_CAVOK そもそも回答が左に来ているのは間違い。 個数*単価 = 代金 Q.E.D. という文法のプログラミング言語を作る所から始める。
— Dan Kogai (@dankogai) 2014, 6月 13
JavaScript で書いてみた。これをもっと簡単に、手っ取り早く書けるようなプログラミング言語を作るってことかなぁ〜
コード(BBEdit, Emacs)
var pre = document.querySelector('#pre0'),
select = document.querySelector('#select0'),
num = document.querySelector('#n0'),
button = document.querySelector('#b0'),
select1 = document.querySelector('#select1'),
button1 = document.querySelector('#b1'),
has_value = function (connector) {
return connector('has_value');
},
get_value = function (connector) {
return connector('value');
},
set_value = function (connector, new_value, informant) {
return connector('set_value')(new_value, informant);
},
forget_value = function (connector, retractor) {
return connector('forget')(retractor);
},
connect = function (connector, new_constraint) {
return connector('connect')(new_constraint);
},
inform_about_value = function (constraint) {
return constraint('I have a value');
},
inform_about_no_value = function (constraint) {
return constraint('I lost my value');
},
multiplier = function (m1, m2, product) {
var process_new_value = function () {
if ((has_value(m1) && (get_value(m2) === 0)) ||
(has_value(m2) && (get_value(m1) === 0))) {
return set_value(product, 0, me);
}
if (has_value(m1) && has_value(m2)) {
return set_value(product, get_value(m1) * get_value(m2), me);
}
if (has_value(product) && has_value(m1)) {
return set_value(m2, get_value(product) / get_value(m1), me);
}
if (has_value(product) && has_value(m2)) {
return set_value(m1, get_value(product) / get_value(m2), me);
}
},
process_forget_value = function () {
forget_value(product, me);
forget_value(m1, me);
forget_value(m2, me);
return process_new_value();
},
me = function (request) {
switch (request) {
case 'I have a value':
return process_new_value();
case 'I lost my value':
return process_forget_value();
default:
throw 'Unknown request -- MULTIPLIER ' + request;
}
};
connect(m1, me);
connect(m2, me);
connect(product, me);
return me;
},
probe = function (name, connector) {
var print_probe = function (value) {
pre.textContent += name + ' = ' + value + '\n';
},
process_new_value = function () {
return print_probe(get_value(connector));
},
process_forget_value = function () {
return print_probe('?');
},
me = function (request) {
switch (request) {
case 'I have a value':
return process_new_value();
case 'I lost my value':
return process_forget_value();
default:
throw 'Unknown request -- PROBE ' + request;
}
};
connect(connector, me);
return me;
},
make_connector = function () {
var value = false,
informant = false,
constraints = [],
set_my_value = function (newval, setter) {
if (!has_value(me)) {
value = newval;
informant = setter;
return for_each_except(setter, inform_about_value,
constraints);
}
if (value !== newval) {
throw '設定済み: ' + [value, newval];
}
return 'ignored';
},
forget_my_value = function (retractor) {
var ary = constraints.slice();
if (retractor === informant) {
informant = false;
return for_each_except(retractor, inform_about_no_value,
ary);
}
return 'ignored';
},
connect = function (new_constraint) {
if (constraints.indexOf(new_constraint) === -1) {
constraints.unshift(new_constraint);
}
if (has_value(me)) {
inform_about_value(new_constraint);
}
return 'done';
},
me = function (request) {
switch (request) {
case 'has_value':
return informant ? true : false;
case 'value':
return value;
case 'set_value':
return set_my_value;
case 'forget':
return forget_my_value;
case 'connect':
return connect;
default:
throw 'Unknown operation -- CONNECTOR ' + request;
}
};
return me;
},
for_each_except = function (exception, procedure, ary) {
var i = 1;
var loop = function (ary) {
var ary1 = ary.slice();
if (ary1.length === 0) {
return 'done';
}
if (ary1[0] === exception) {
ary1.shift();
return loop(ary1);
}
procedure(ary.shift());
return loop(ary);
},
ary1 = ary.slice();
return loop(ary1);
},
n = make_connector(),
price = make_connector(),
total = make_connector(),
value;
multiplier(n, price, total);
probe('個数', n);
probe('単価', price);
probe('代金', total);
button.onclick = function () {
if (num.value.match(/\D/) || num.value === '') {
pre.textContent += '数値を設定する必要があります\n';
} else {
value = parseInt(num.value, 10);
try {
switch (select.value) {
case 'n':
return set_value(n, value, 'kamimura');
case 'price':
return set_value(price, value, 'kamimura');
case 'total':
return set_value(total, value, 'kamimura');
}
} catch (e) {
pre.textContent += e + '\n';
}
}
};
button1.onclick = function () {
try {
switch (select1.value) {
case 'n':
return forget_value(n,'kamimura');
case 'price':
return forget_value(price, 'kamimura');
case 'total':
return forget_value(total, 'kamimura');
}
} catch (e) {
pre.textContent += e + '\n';
}
};
出力結果
個数 × 単価 = 代金
0 コメント:
コメントを投稿