LINUX.ORG.RU

Скриптовый функциональный язык (с иммутабельностью)

 , ,


0

3

Собственно сабж. Пых, руби или пайтон - императивщина, хоть и с элементами. А было бы очень неплохо всякие вебоподелки делать на языке, в котором была иммутабельность из коробки, if был бы выражением, удобная трансформация списков и т.д. Может есть какой «молодой и динамично развивающийся» и без привязки к JVM/Mono/...?

★★★
Ответ на: комментарий от DarkEld3r
auto i = a == b ? (x+=10, std::cout<<"foo", x) : (x+=20, x);

или

auto i = a == b ? 
    []() {
        std::cout << "foo" << std::endl;
        return 42;
    }() : []() {
        std::cout << "foo" << std::endl;
        return 24;
    }();

Во втором случае лямбды заинлайнятся: http://goo.gl/wCnyQa , а значит кроме оргии скобок минусов по сравнению с обычным if нет. Очевидно, никто так на С++ не пишет, но условию «if был бы выражением» С++ соответствует вполне.

anonymous
()
Ответ на: комментарий от h8

Не совсем понял, что ты хочешь, что-то вроде такого

  auto a = [](){ 
    try { return make_optional(foo()); } 
    catch(...) { return optional<int>(); } }();
  if(a)
  { 
     std::cout << *a;
  }
?

anonymous
()
Ответ на: комментарий от Debasher

Hylang

судя по issues — этим пользоваться не очень приятно)

Bad_ptr ★★★★★
()

Без привязки не получится.

Ибо недопрограммки никому, кроме кульхацкеров, IRL не нужны.

Однозначный ответ - Groovy.

Есть отличия от Джавы в инициализации массивов [], в switch по enum, явным указанием ClassLoader при загрузке properties, однако, переход занимает один день.

PS. @Immutable имеет место быть.

Bioreactor ★★★★★
()
Ответ на: комментарий от anonymous

if должен что-то возвращать, поэтому else обязателен

Схренаб else обязателен?

loz ★★★★★
()
Ответ на: комментарий от DarkEld3r

Если if является выражением, то тернарный оператор не нужен. Ну и if читабельнее, если условие не элементарное. Да и обычно, это идёт вместе с "(почти) всё - выражение".

Это все мелочи

Какой?

Хотя бы тот, что можно использовать условные конструкции как first-класс объекты:


unless := method(
  if(call evalArgAt(0), call evalArgAt(2), call evalArgAt(1))
)

function := method(
 args := call message arguments
 performWithArgList(args at(0) code, args slice(1) map(x, doMessage(x)))          
)

write( function(if, 1>2, 1, 2), "\n", function(unless, 1>2, 1, 2) )

# out:
#  2
#  1
, например.

nuboquest
()
Ответ на: комментарий от anonymous

Вот если бы if был функцией, тогда да, профит.

if может быть функцией только в реболе, в обычных языках он обязан быть специальной формой.

loz ★★★★★
()
Ответ на: комментарий от nuboquest

Ну ок, в реболе можно указывать конкретно какие аргументы вычисляются, а какие нет.

loz ★★★★★
()

По сабжу языков с иммутабельностью и так то почти и нет, тем более скриптовых, когда ее еще и не заоптимизируешь хорошо, а всякие прелести скриптования типа быстрой правки кода и его загрузки пропадают.

loz ★★★★★
()
Ответ на: комментарий от anonymous

A little code sample that prints the first 1000 Fibonacci numbers:
[code]extern int puts(char*);

do (puts.str) (take 1000 (fibs 0L 1L)) with fibs a b = a : fibs b (a+b) & end;

Вся суть.

anonymous
()
Ответ на: комментарий от loz

Ну пускай будут не скриптовые, а хотя бы по удобству скоростного говнокодинга будут приближатся к пайтону, например.

h8 ★★★
() автор топика
Ответ на: комментарий от h8

Сомневаюсь, что найдется хоть один скриптовый язык не превосходящий пистон по данному критерию раза в 2 - 3.

anonymous
()
Ответ на: комментарий от anonymous

Наброс не оче. Трай хардер.

h8 ★★★
() автор топика
Ответ на: комментарий от loz

Ты вызови function(if) так, чтобы не вычислять аргументы.


unless := method(
  if(call evalArgAt(0), call evalArgAt(2), call evalArgAt(1))
)

function := method(
 args := call message arguments
 lst :=list(call evalArgAt(1)) append (args at(2)) append (args at(3))
 doMessage(performWithArgList(args at(0) code, lst))
)

function(if, 1>2, 1 print, 2 print)
function(unless, 1>2, 1 print, 2 print)

# out:
# 21
nuboquest
()
Ответ на: комментарий от anonymous

extern int puts(char*); do (puts.str) (take 1000 (fibs 0L 1L)) with fibs a b = a : fibs b (a+b) & end;

Вся суть.

Ну я предупреждал что это красиво! С «С» интегрируется как родной: It uses the C puts function to do the printing. Ленивый: Note that if you remove the take 1000, all Fibonacci numbers will be printed (press Ctrl-C when you get bored).

Интерпретатор под всё, но можно компилировать. Так что ж тебе собака ещё надо?!?!

Ы\

anonymous
()
Ответ на: комментарий от anonymous

Очевидно, никто так на С++ не пишет

Вот именно. Я на С++ пишу, если что. Но иметь «нормальный» if удобно. Плюс не надо делать отдельно тернарный оператор, отдельно if.

Первый вариант не катит - так не объявишь промежуточную переменную, например.

но условию «if был бы выражением» С++ соответствует вполне.

Ну вообще-то нет. Ведь ты не if используешь.

DarkEld3r ★★★★★
()
Ответ на: комментарий от nuboquest

Хотя бы тот, что можно использовать условные конструкции как first-класс объекты:

Да, про это не подумал.

DarkEld3r ★★★★★
()
Ответ на: комментарий от h8

Да, типа такого. Только выглядит страшно.

Опять же, смотря с чем сравнивать. Возможности делать цепочки вызовов с Maybe (то есть ничего не делать, если у нас Nothing), как в хаскеле, конечно, нет. Но этого и в расте пока нет, вроде.

Но главное то, что в расте нет исключений. Панику ты никак не перехватишь, разве что на границе таска. А делать интерфейсы возвращающие optional<value> или pair<value, error> никто не мешает. И выглядеть будет не так уж плохо, хотя паттерн матчинга и нет.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Тут скорее не паттерн матчинг нужен, а traversable.

h8 ★★★
() автор топика
Ответ на: комментарий от nuboquest

Но у него синтаксис не на s-выражениях, такой же гемор работать с цитированным кодом как и везде.

loz ★★★★★
()
Ответ на: комментарий от loz

s-выражения, пресловутый code-as-data, это миф. Там у тебя выражения представлены списками, а тут строками и объектами, вот и вся разница. Второй подход проще, только и всего. К тому же, если сравнивать конкретно с CL и scheme, то там к тому же код не доступен в рантайме, так что лисп в целом сосет. Например, такая конструкция как у меня в примере, там невозможна вообще.

nuboquest
()
Ответ на: комментарий от nuboquest

Например, такая конструкция как у меня в примере, там невозможна вообще

Непонял, какая часть конструкции? Я в io просто не понимаю нихрена.

loz ★★★★★
()
Ответ на: комментарий от loz

Да практически любая


(define f (lambda(arg) (arg #f (write 1) (write 2))))

(f if)

;  "error": invalid application: (#<syntax if> #f #<undef> #<undef>)
;  12

макросы не первоклассные объекты, следовательно, в рантайме никакую лень обеспечить невозможно.

nuboquest
()
Ответ на: комментарий от nuboquest

следовательно, в рантайме никакую лень обеспечить невозможно.

Ну это следует хотябы из того, что макросов в рантайме уже не существует, но if вобще не макрос, а специальная форма.

loz ★★★★★
()
Ответ на: комментарий от anonymous

Интерпретатор под всё, но можно компилировать.

Нужно только понимать, что он term rewriting, а отсюда все «особенности» таких языков.

mix_mix ★★★★★
()
Ответ на: комментарий от anonymous

Вся суть.

Язык безумно красивый, на самом деле. Вот, например, полная реализация AVL-деревьев.

nonfix nil; 

avltree xs = foldl insert nil xs; 

null nil = 1; 
null (bin _ _ _ _) = 0; 

insert nil y = bin 1 y nil nil; 
insert (bin h x t1 t2) y 
   = rebal (mknode x (insert t1 y) t2) if x > y; 
   = rebal (mknode x t1 (insert t2 y)); 

delete nil y = nil; 
delete (bin h x t1 t2) y 
   = rebal (mknode x (delete t1 y) t2) if x > y; 
   = rebal (mknode x t1 (delete t2 y)) if x = join t1 t2; 

join nil t2 = t2; 
join t1@(bin _ _ _ _) t2 
   = rebal (mknode (last t1) (init t1) t2); 

init (bin h x t1 nil) = t1; 
init (bin h x t1 t2) = rebal (mknode x t1 (init t2)); 

last (bin h x t1 nil) = x; 
last (bin h x t1 t2) = last t2; 

mknode x t1 t2 = bin (max (height t1) (height t2) + 1) x t1 t2; 

height nil = 0; 
height (bin h x t1 t2) = h; 

slope nil = 0; 
slope (bin h x t1 t2) = height t1 - height t2; 

rebal t
   = shl t if slope t == -2; 
   = shr t if slope t == 2; 
   = t; 

rol (bin h x1 t1 (bin h2 x2 t2 t3)) 
   = mknode x2 (mknode x1 t1 t2) t3; 

ror (bin h1 x1 (bin h2 x2 t1 t2) t3) 
   = mknode x2 t1 (mknode x1 t2 t3); 

shl (bin h x t1 t2)
   = rol (mknode x t1 (ror t2)) if slope t2 == 1; 
   = rol (bin h x t1 t2); 

shr (bin h x t1 t2)
   = ror (mknode x t1 (ror t2)) if slope t2 == -1; 
   = ror (bin h x t1 t2);

mix_mix ★★★★★
()
Ответ на: комментарий от anonymous

Блядский лор

if' True t _ = t
if' False _ f = f
anonymous
()

А было бы очень неплохо всякие вебоподелки делать на языке, в котором была иммутабельность из коробки, if был бы выражением, удобная трансформация списков и т.д.

Erlang же.

Почему кстати обязательно без привязки к JVM/Mono/...? С языком ВУ такого уровня всё равно будет идти свой хитрожопый рантайм, как ты его не назови.

migesok
()
Ответ на: комментарий от Debasher

Groovy - это для больших корпораций.

Банки, крупные компании - ну те, что в Сити

http://demworld.ru/var/albums/real/5399.jpg?m=1366142370

В Ваш мир я не вылезаю - на ЛОРе вполне достаточно адекватных людей, знающих разницу между классами и интерфейсами.

Умничать будете на собеседовании.

Bioreactor ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.