LINUX.ORG.RU

DrRacket and elisp окончательно запутался

 ,


0

3

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

#lang racket
(define *distance-lst* (list 1 2 3 4 5 6))

(define *A-distance* 3)
(define *left-A-lst* '())

(define d-lst (length *distance-lst*))
(define *output-lst* '())
(define (slice input-lst a output-lst)
  (if (< (first input-lst) a)
      (slice (cons (first input-lst) output-lst)
             a
             (set! input-lst (rest input-lst)))
      output-lst))
     
;;(define (split-lst lst-input a lst-output)
;  (if (< (first lst-input) a)
 ;     (split-lst (set! lst-input (rest lst-input))
  ;                     a
   ;                    (set! lst-output
    ;                         (cons
     ;                         (first lst-input) lst-output)))
 ; lst-output))

(slice *distance-lst* *A-distance* *left-A-lst*)

и вот на elisp и работает как надо, задолбало, что не так не могу понять эту ракету

(defun slice (input-lst a output-lst)
(if (< (car input-lst) a)
(slice (cdr input-lst) a (push (car input-lst) output-lst))
output-lst))

(nreverse (slice '(1 2 3 4 5 6) 5 '()))

Ответ на: комментарий от monk

Если знаешь синтаксис и семантику языка, то это также просто как чтение

Нет, не также. Например ты можешь знать значок интеграла и все буковки вроде знакомые. Но даже зная как вычислить значение интеграла, на это вычисление нужно будет время и бумага. Вряд ли ты сходу вычислишь его в голове. Можно запомнить значение ходовых интегралов, с которыми ты часто работаешь, но так как вариантов бесконечное количество, то всё равно регулярно будет возникать ситуация, что тебе нужно подумать и посчитать. А всё потому, что сложность этого языка выше возможностей человека. Также и с языками программирования. Даже не надо далеко ходить, в обычном C++ смотришь на эти «ехал шаблон через шаблон» и не понимаешь сходу что тут вообще происходит. Программисты на крестах натаскиваются на типовые применения шаблонов, как на типовые интегралы и им может казаться, что всё просто и понятно, но стоит только встретить что-то нетиповое и им также приходится «считать на бумажке».

считаете, что отслеживание логики программы по cmp/jz так же просто, как и по if

Да, также просто, при условии, что писал человек. Человек не напишет сложно, он сложно не может. Кажущаяся сложность ассемблерных листингов сегодня вызвана тем, что их генерирует компилятор. И ещё раз повторю, что я говорю не о сложности логики, а о сложности выражений языка как таковых. В примерном ассемблерном mov rax, 42 нет ничего слишком сложного - число 42 кладём в регистр rax, взять что-то положить куда-то это простая, натуральная операция для человека и поэтому понятная интуитивно. Натренировавшись можно читать команды ассемблера как слова текста, а вот с интегралами так не получится никогда.

no-such-file ★★★★★
()
Ответ на: комментарий от Virtuos86

Только реальный код приходится писать, используя чуть больше, чем эти простые принципы

Об том и речь. Программирование сильно усложнилось, так что даже один человек редко может что-то дельное написать, нужен коллектив. Тот же линукс требует труда огромного количества людей, масштабов индустрии.

вот с их использованием возникают поначалу жесткие траблы

Именно. Мой тезис в том, что возможности человека ограничены, поэтому попытки внедрять в языках более обобщающие обобщения, призванные совладать со сложностью, не работают, потому что эти концепции оказываются с одной стороны ненатуральными для человека, не ложащимися на его примитивные понятия о реальности («взял камень, положил в карман» - mov rax, 42), а с другой и не отражают реальность вполне обобщённо (те же split и split_mut отличный пример, в идеальном случае должен был бы быть один split для всего). Я считаю что эти попытки бесполезные, потому что сложность не уменьшится и если для написания программы нужен год работы 10 человек, то так и будет независимо от языка. А уж пишут ли они по 10к строк в день на дубовом языке, или 1 строку в месяц на изысканном - без разницы.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

Да, также просто, при условии, что писал человек. Человек не напишет сложно, он сложно не может.

Еще как может, на том же бейсике (еще старом с номерами строк goto и gosub) сам в студенчестве так писал что через полгода не мог разобраться. После попадались такое же фортрановское и сишное творчество с goto.

Натренировавшись можно читать команды ассемблера как слова текста

Ассемблеры тоже разные, интеловский понятно ведет свое наследие от человекочитаемых вариантов поэтому относительно несложен, но все равно сложнее си, но можно взять скажем тот же brainfuck который по сути простейшая реализация машины Тьюринга и читать (и писать) на нем уже сложнее чем на си или даже хаскеле.

а вот с интегралами так не получится никогда.

Из языков программирования по сложности могут соперничать с высшей математикой только всякие interactive theorem prover типа Coq. С большинством языков программирования включая и haskell и С++ и тем более rust (он проще того же C++, просто входной барьер достаточно высок) натренироваться можно без проблем.

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

так писал что через полгода не мог разобраться

Это всё таки проблемы другого плана, я не про них говорю. Само по себе goto просто и понятно. На естественном языке тоже можно говорить запутанно и даже генерировать бред и шизофазию (среди которой всё таки может быть какой-то смысл, хоть и трудноуловимый). Я говорю о сложности восприятия языка программирования как текста. Когда на отдельные слова такого текста навешан сложный смысл, то предложения получаются слишком сложными.

(Кстати когда ты не смог разобраться, ты потратил столько же времени сколько для написания? Почему-то мне кажется что гораздо меньше и плюнул на это дело.)

читать (и писать) на нем уже сложнее чем на си или даже хаскеле

Разумеется. Я не рассматриваю эзотерические языки, но вообще с ними та же проблема, они не отвечают устройству мозга человека. Вообще идеальный язык для человека это естественный язык, но для машин он не очень подходит. Поэтому хорошими языкам программирования являются такие которые с одной стороны отражают устройство машины, а с другой сохраняют естественность человеческого языка. Ярким примером такого является язык Си. Лисп тоже неплох, но у него уклон в естественность, и поэтому меньшая машинная эффективность (правда эту проблему в своё время успешно решали). А вот хаскели и расты это попытка найти какой-то более общий знаменатель, выйти за пределы этой дихотомии. Делать это предлагается за счёт освоения новых обобщающих вычисления концепций которые будут одинаково удобны и человеку и машине. Но получается пока не очень, люди как-то не оценили, потому что по большому счёту причин для перехода на языки нового уровня пока нет.

натренироваться можно без проблем

Но не нужно. Я об этом в самом первом посте на эту тему написал. Нет предпосылок для массового перехода на такие языки. И вряд ли они появятся, как мне кажется, потому что с точки зрения теории вычислимости ничего нового они не дают, с точки зрения экономики тоже выгода сомнительна. Матан, как я уже писал, создавался чтобы постигать непостижимое, а эти языки - нет. Мне кажется это тупиковое направление, как в своё время тупиковыми были PL/I и т.п.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 2)
Ответ на: комментарий от no-such-file

получается пока не очень, люди как-то не оценили

Кстати, я тут подумал, что интересно было бы попробовать использовать раст в литературном программировании. Оно как раз призвано преодолеть разрыв между машинной программой и естественным текстом и не прижилось, как мне кажется, именно потому, что языки программирования в своём развитии оптимизировались в этом отношении и сами стали выполнять роль более-менее естественного текста. Но для языков где с естественностью и натуральностью туго, литературное программирование может быть выходом из положения. Вот бы растоманам интегрировать ЛП в свою экосистему, так чтобы модули писались с ЛП и компилятор это понимал из коробки. Было бы здорово.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 2)
Ответ на: комментарий от no-such-file

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

Зачем его вычислять? Читая просто знаешь, что это площадь под указанной функцией.

Даже не надо далеко ходить, в обычном C++ смотришь на эти «ехал шаблон через шаблон» и не понимаешь сходу что тут вообще происходит.

Опять же:

map<string, map<int, int> > d;

однозначно читается как «словарь с ключом-строкой и значением-словарём, у которого ключи и значения целые числа». И для этого не надо читать исходники STL. И не надо писать пару сотен строк реализации, как пришлось бы на ассемблере или даже Си.

но стоит только встретить что-то нетиповое и им также приходится «считать на бумажке».

Например? Я не могу представить себе ситуацию, чтобы потребовалось выяснять, во что раскрывается работающий шаблон.

Да, также просто, при условии, что писал человек.

Вот программа, написана человеком. Что она делает?

START:
		pop	eax			; get argc
		dec	eax
		jnz	has_arguments
		pop	ebx
		jmp	use_stdin
has_arguments:
		pop	eax			; get argv[0]
get_next_arg:		
		pop	ebx
		test	ebx,ebx
		jz	near no_more_args
		
		mov	esi,opts_table		; table
		mov	edi,_lines
		xor	ecx,ecx
		mov	cl,3
		mov	dl,100b
fetch_from_table:
		lodsw
		cmp	word [ebx],ax		; is it our option?
		jnz	try_next_option		; nope
		or	byte [flgs],dl		; set bitflag
		jmps	get_next_arg
		;pop	ebx			; get the next argument off the stack
try_next_option:
		shr	dl,1	
		xor	eax,eax			; clear counters
		stosd	
		loop	fetch_from_table
		
just_open_it:		
		xor	eax,eax
		cmp	byte [ebx],'-'		; user wants STDIN
		jz	use_stdin
		
		mov	edi,ebx			; save filename
		
		mov	byte [_opened_a_file], 1
		sys_open EMPTY,O_RDONLY
		test	eax,eax
		js	near error
		jmp	set_filehandle
use_stdin:
		mov	byte [_use_stdin], 1
set_filehandle:
		mov	ebp,eax
read_file:		
		sys_read ebp,buf,buf_size
		test	eax,eax
		js	near error
		jz	print_results
		
		mov	esi,ecx			; esi=ecx=buf
		mov	ecx,eax			; ecx=bites read

		xor	eax,eax
buf_is_not_empty:
		mov	ebx,_bytes
		lodsb				; get next char
		inc	dword [ebx]		; count this char
		sub	ebx,4			; ebx=_words
		
		cmp	al,' '
		jz	inside_a_word
		cmp	al,9
		jz	inside_a_word
		cmp	al,10
		jz	inside_a_word
		mov	ah,1			; set flag (inside a word)
		jmp	count_lines
inside_a_word:
		test	ah,ah			; inside a word?
		jz	count_lines		; nope
		inc	dword [ebx]		; count this word
		xor	ah,ah			; reset flag
count_lines:		
		sub	ebx,4			; ebx=_lines
		
		cmp	al,10			; is it a '\n' ?
		jnz	not_a_new_line
		inc	dword [ebx]		; count this new line
not_a_new_line:		
		dec	ecx			; 
		jnz	buf_is_not_empty
		jmp	read_file
		
print_results:
		push	edi			; save filename

		xor	ecx,ecx
		mov	bl,[flgs]
		mov	cl,3
		mov	dl,100b
		mov	esi,_lines
next_counter:
		push	ecx
		lodsd
		test	bl,bl
		jz	print_it_now
		test	bl,dl
		jz	skip_it
print_it_now:
		mov	edi,num_buf
		mov	ecx,edi
		call	bin_to_dec
		call	print
skip_it:		
		shr	dl,1
		pop	ecx
		loop	next_counter
		
		pop	ecx			; restore filename
		cmp	byte [_use_stdin], 1
		jz	print_newline
		call	print
print_newline:

		mov	ecx,cr			; print \n
		call	print

		jmp	get_next_arg	

no_more_args:
		cmp	byte [_opened_a_file], 0
		jne	true_exit
		mov	byte [_opened_a_file], 1
		xor	eax, eax
		jmp	use_stdin
true_exit:
		xor	ebx,ebx		
		jmp	do_exit
error:		
		xor	ebx,ebx
		dec	ebx
do_exit:
		sys_exit		

;
; -------------------------------- procedures ---------------------------------
;

; ecx=string to print
print:
		pushad
				
		mov	esi,ecx
		call	strlen
	
		; ecx already holds string, edx holds strlen
		sys_write STDOUT

		popad		
		ret

; esi=string
; edx=strlen
strlen:
		push	eax
		push	esi
		
		xor	eax,eax
		mov	edx,eax
		dec	edx
.do_strlen:
		inc	edx
		lodsb
		test	al,al
		jnz	.do_strlen
		
		pop	esi
		pop	eax
		ret

; eax=number	edi=buf to store string
; -
bin_to_dec:
		pushad
		
		xor	ecx,ecx		
		mov	ebx,ecx
		mov	bl,10
.div_again:		
		xor	edx,edx
		div	ebx
		add	dl,'0'
		push	edx
		inc	ecx
		test	eax,eax
		jnz	.div_again
.keep_popping:		
		pop	eax
		stosb
		loop	.keep_popping
		
		; put \t\x0
		mov	ax,0x009
		stosw
		
		popad
		ret	

		DATASEG

opts_table:
		dw	"-l"
		dw	"-w"
		dw	"-c"

flgs:		db	0	

cr:		db	10,0
		
		UDATASEG
				

_lines:		resd	1
_words:		resd	1
_bytes:		resd	1
_use_stdin:	resb	1
_opened_a_file:	resb	1

num_buf:	resb	16
buf:		resb	4096
buf_size	equ	$-buf

Сколько времени понадобилось, чтобы её понять?

В примерном ассемблерном mov rax, 42 нет ничего слишком сложного - число 42 кладём в регистр rax, взять что-то положить куда-то это простая, натуральная операция для человека и поэтому понятная интуитивно.

Но непонятно, почему именно 42 и почему в rax. Эквивалентное сишное «return ENOMSG» гораздо очевиднее.

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

Читая просто знаешь, что это площадь под указанной функцией

ЛОЛ, ну да, а слово template это в общем какой-то шаблон.

однозначно читается как «словарь с ключом-строкой и значением-словарём, у которого ключи и значения целые числа».

Ах, если б они этим ограничились, но их же Александреску покусал. Кстати, твоё понимание не полное, там ещё аллокатор и т.д. надо таки смотреть исходники.

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

Ну, ты наверное не пишешь на крестах.

Что она делает?

Мне лень тратить на это своё время. Человеку сколько потребовалось чтобы её написать и отладить? Вот я столько тратить не хочу. Смысл каждой строки однако вполне понятен и никаких «там ещё аллокатор и т.д.»

Но непонятно, почему именно 42 и почему в rax. Эквивалентное сишное «return ENOMSG» гораздо очевиднее.

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

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 2)
Ответ на: комментарий от no-such-file

а слово template

А слово template обозначает, что как правило дальше описание шаблона.

Ах, если б они этим ограничились, но их же Александреску покусал.

А с его шаблонами что не так? Библиотека Loki достаточно легко используется.

там ещё аллокатор и т.д

Для использования это неважно.

Мне лень тратить на это своё время. Человеку сколько потребовалось чтобы её написать и отладить? Вот я столько тратить не хочу.

А аналогичный сишный код понимается примерно за 30 секунд.

Смысл каждой строки однако вполне понятен и никаких «там ещё аллокатор и т.д.»

Тогда твой идеальный язык Brainfuck: всего 4 команды никаких «там ещё переменная», «там ещё функция». Смысл каждой команды очевиден.

monk ★★★★★
()
Ответ на: комментарий от no-such-file

Само по себе goto просто и понятно. Но уже несколько штук в одной функции могут быть сложнее матана для разбора.

(Кстати когда ты не смог разобраться, ты потратил столько же времени сколько для написания? Почему-то мне кажется что гораздо меньше и плюнул на это дело.)

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

Разумеется. Я не рассматриваю эзотерические языки, но вообще с ними та же проблема, они не отвечают устройству мозга человека.

Это не столько эзотерический язык сколько минимально возможный ассемблер и обычный ассемблер не далеко от него ушел, и так же не отвечает устройству мозга человека.

Вообще идеальный язык для человека это естественный язык, но для машин он не очень подходит.

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

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

Си это яркий пример эволюции, когда побеждает не самый лучший, а тот кто оказался в нужном месте в нужное время и получил максимум ресурсов для развития. И никакой естественности человеческого языка он не сохраняет, те же правила объявления типов худшие среди конкурентов.

Лисп тоже неплох, но у него уклон в естественность, и поэтому меньшая машинная эффективность (правда эту проблему в своё время успешно решали).

Какая естественность в голом AST? По моему он очень далек от естественного языка и мышления. Хотя это конечно сильно субъективно. Вот мне например кажется очень естественным Forth (так как начинал с программируемых калькуляторов), но большинство современных программистов впадают в полный ступор увидев листинг на форте. Так что все это только дело привычки.

А вот хаскели и расты это попытка найти какой-то более общий знаменатель, выйти за пределы этой дихотомии. Делать это предлагается за счёт освоения новых обобщающих вычисления концепций которые будут одинаково удобны и человеку и машине.

Раст да, как и C++, пытается угодить машине и при этом не потерять возможности абстрагирования, но это естественно для (около) системных языков. Но хаскель и даже более простой OCaml уже точно не пытаются даже быть удобными машине, они пытаются быть очень удобными именно человеку, но с одним требованием у человека должно быть какое никакое, но математическое мышление.

Но не нужно.

И лисп и форт также оказались по большому счету не нужны. И smalltalk (который ближе все выше перечисленных к естественному мышлению) тоже не прижился. Но C++ жив и вполне успешен, Ява и C# тоже превращаются в сложные языки (сравнимы с растом по сложности), хотя начинали как простые. Да и Scala заняла вполне свою нишу. Думаю и раст вполне приживется.

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

А зачем массовый переход? Сейчас какая нибудь узкая ниша может дать работу очень приличному количеству людей.

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

А аналогичный сишный код понимается примерно за 30 секунд.

Так там и кода меньше и к естественному языку ближе и пишется он также за 30 секунд условно. В 100500 раз повторю, я не обсуждаю сложность понимания алгоритма в целом, а только сложность понимания отдельных выражений, слов языка. Пример с интегралом, мне кажется предельно наглядным. Нет, опять ты суешь мне своё «а вот тебе разложение в ряд, поди-ка посчитай». Я утверждаю, что сложение проще, чем интегрирование. Даже если сложить нужно дохрилион чисел. Это всё равно понятно даже первокласснику, а интеграл нет.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от anonymous

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

Да, но природа ничем лучшим нас не наградила, увы.

поэтому человек придумал например математику и кучу научных и профессиональных диалектов

Не столько поэтому, а потому что хотелось осмыслить бытие. Цель достойная и сложный язык тут неизбежен. А какая цель преследуется, что делает неизбежность раста?

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

Да, потому что всё-таки для машин естественный язык не подходит, нужен компромисс. А эти коболисты и ПЛщики как раз упарывались в естественность. Упарывание в абстракции как на расте - того же сорта извращение и ждёт его тоже самое что и КОБОЛ.

пример эволюции, когда побеждает не самый лучший

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

Какая естественность в голом AST? По моему он очень далек от естественного языка и мышления

При чём тут AST? Главное в лиспе это символы и repl, т.е. самая что ни есть естественная форма для человека - общение путём составления предложений. Настолько естественная, что на нём даже пытались изучать и имитировать мышление человека (лингвистический подход к ИИ).

хаскель и даже более простой OCaml уже точно не пытаются даже быть удобными машине

математическое мышление

Математическое мышление это и есть «машина», определённая чёткой, формальной логикой. Просто тут в базе непривычная «машина Чёрча» вместо привычной Машины Тьюринга.

И лисп и форт также оказались по большому счету не нужны

Потому что кроме соображений «хорошести языка» есть соображения экономики. Если буржуям выгодно чтобы ты копал уголь урановым ломом, ты будешь копать уголь урановым ломом. Ситуация стала немного выправляться когда появились излишества, вроде колоссальной вычислительной мощи, безразмерной памяти и т.д. Начался ренессанс языков с уклоном в естественность. Даже как-то Лисп ожил.

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

Вот тут я соглашусь. В таких узких нишах раст вполне может найти применение (привет КОБОЛ). Вопрос только в том, где эти ниши? Системное программирование оккупировано Си и желать там чего-то другого странно, потому что никаких дополнительных абстракций там не надо, а важно полное отражение языком архитектуры машины. В прикладном программировании выбор очень широкий, не представляю зачем там могут понадобиться уникальные для раста концепции и свойства.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 3)
Ответ на: комментарий от no-such-file

В 100500 раз повторю, я не обсуждаю сложность понимания алгоритма в целом

Было утверждение:

Так вот мой тезис в том, что сложность программы при этом не уменьшится и количество усилий для её понимания тоже, поэтому осмыслить эти 10к всё равно не получится, а язык будет неизбежно сложным настолько, что для осмысления даже одного выражения нужно будет медитировать пару месяцев, как над пониманием сложной математической теоремы.

Если ты от него отказываешься, спору нет. Если согласен, что на одном языке программа пишется и читается адски долго, а на другом она же в 10 раз короче и понимается в 100 раз быстрее, тогда спорить не о чем.

monk ★★★★★
()
Ответ на: комментарий от no-such-file

На естественном языке тоже можно говорить запутанно

На естественном языке без использования математических символов или синтаксиса языка программирования практически невозможно объяснить более менее сложные абстракции и алгоритмы.

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

Если ты от него отказываешься, спору нет

Ээм, а в чём противоречие? 10к строк интегралов сложнее понять чем 10М строк сложений. И написать тоже, потому что перед тем как написать нужно это осмыслить. Осмыслить «сумму площадей трапеций под графиком» проще, чем найти соответствующее аналитическое выражение.

Если тебе хочется подокпываться, то я тоже так могу. Я не утверждал что это работает в обратную сторону, и что если 10к строк размазать на 10М, то будет также понятно (тем более что я вообще не касаюсь сложности алгоритмов, а только сложности понятий самого языка). Поэтому я не пойму на чём ты меня пытаешься поймать? Заканчивай ломиться в открытую дверь. Причём я тебе это уже говорил, но ты всё равно продолжаешь.

на одном языке программа пишется и читается адски долго, а на другом она же в 10 раз короче и понимается в 100 раз быстрее

В общем случае нет. Конкретно программа на расте не будет в 10 раз короче и не будет пониматься в 100 раз быстрее чем эквивалентная программа на Си. Скорее уж наоборот.

Мне кажется, что я уже достаточно прокомментировал попытки приводить в пример brainfuck, что это также противоестественно для человека и затрудняет программирование (хотя само по себе просто для понимания). Не вижу смысла вообще это обсуждать, потому что это банально и никто не проповедует переходить на brainfuck, ассемблер и т.д. А вот расты-хаскели и т.п. языки как раз пытаются представить как серебряную пулю, и в каждой бочке затычку.

На естественном языке без использования математических символов или синтаксиса языка программирования практически невозможно объяснить более менее сложные абстракции и алгоритмы

И что? Мне сколько раз нужно повторить что матан имеет смысл потому что мы вынуждены его применять, чтобы достичь целей познания? Предлагаю и тебе вместо очередной демагогии про brainfuck и попыток прицепиться к словам, ответить мне, какие цели преследует раст, что без него в достижении этих целей невозможно обойтись. А то этот вопрос как-то повис в пустоте.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

Не вижу смысла вообще это обсуждать, потому что это банально и никто не проповедует переходить на brainfuck, ассемблер и т.д.

Вполне проповедуют, сейчас в роли таких простых языков это go и си, раньше носились например с обероном и с явой (пока она еще была очень простой).

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

ответить мне, какие цели преследует раст, что без него в достижении этих целей невозможно обойтись

Из заявленного: безопасность работы с памятью без сборщика мусора.

Из реализованного: типизированные шаблоны, сопоставление по образцу, макросы.

Всё это вместе позволяет писать очень лаконичный и понятный код:

Примерный аналог той портянки на ассемблере:

    let args = env::args();
    let path_arg = args.skip(1).nth(0).unwrap();
    let path = Path::new(&path_arg);

    let mut file = File::open(&path).unwrap();
    let mut contents = String::new();
    file.read_to_string(&mut contents).unwrap();

    let mut word_count = 0;
    for line in contents.lines() {
        word_count += line.split_whitespace().count();
    }

    println!("{} words found", word_count);
monk ★★★★★
()
Ответ на: комментарий от silver-bullet-bfg

Это не явное поведение

«Неявное» - это непривычное (в данном случае)? Тут ничего не поделаешь, в разных языках могут быть свои особенности. Оно объясняется в учебнике в самом начале, а перед тем как писать на языке хорошо быть хоть что-то почитать.

Ну и перемещение по умолчанию к случайным ошибкам не приводит. Максимум - не скомпилируется. Зато писать меньше, чем с явным перемещением.

Это не очевидно и не явно, если ты не в курсе семантики Rust или С++

Наверное, но что это значит на практике? Нет смысла брать раст или С++, если их низкоуровневость не нужна. А если нужна, то придётся быть в курсе этих вещей.

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

Кстати, твоё понимание не полное, там ещё аллокатор и т.д. надо таки смотреть исходники.

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

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

Очевидно, что аллокатор дефолтный

Совсем не очевидно из контекста. std же не указан. И даже если дефолтный, то это надо иметь в виду.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Совсем не очевидно из контекста. std же не указан.

Ну если придираться, то до конца: откуда мы знаем, что это действительно словарь, а не непонятно что? Мало ли что кому-то взбрело в голову назвать map.

И даже если дефолтный, то это надо иметь в виду.

В 90% (если не больше) случаев не нужно. Особенно, если речь о чтении кода и понимании происходящего.

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

Из заявленного

Во-первых это всё задачи, а не цель. Они не имеют самостоятельной ценности вне конкретной цели.

Во-вторых, главная задача раста, вокруг которой он вообще построен (ИМХО конечно), а именно «безопасность работы с памятью без сборщика мусора» не выполнена. Да и не может быть выполнена принципиально в чём растоманы расписались с помощью unsafe.

Всё это вместе позволяет писать очень лаконичный и понятный код

Это уже похоже на цель, но ведь она не то что не достигнута, а стало только хуже. Потому что всё равно программисту приходится рассуждать (reasoning) о памяти как в языках без GC и при этом добавились дополнительные абстракции. Просто смешно заявлять о «лаконичном и понятном» коде, когда у вас с стандартной библиотеке отдельно split и split_mut и нужно вручную выбрать правильный (т.е. нужно рассуждать о том, о чём по задачам при создания языка хотелось избавится). Кресты и то лучше в этом смысле.

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

Ну если придираться, то до конца

Ну вообще да. Это как раз то о чём я говорю. В крестах простейшие на вид выражения типа a+b требуют дополнительных раздумий о том, что это за операция такая. В противовес этому, если сказано что мы имеем дело с ассемблером x86, то выражение mov rax, 42 предельно понятно без всяких кривотолков.

В 90% (если не больше) случаев не нужно

Вот именно. В 90% случаев эти дополнительные абстракции ненужны. Но они в языке есть и это приходится учитывать независимо от твоих желаний. С растом тоже самое. В 99% случаев его фичи не нужны. Собственно у меня вообще есть сомнения что они хоть где-то нужны. По крайней мене на вопрос «какая цель преследуется, что делает неизбежность раста» мне никто даже не попытался ответить.

PS: ну @monk попытался, но пока не получилось.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 3)
Ответ на: комментарий от no-such-file

Мой тезис в том, что возможности человека ограничены, поэтому попытки внедрять в языках более обобщающие обобщения, призванные совладать со сложностью, не работают, потому что эти концепции оказываются с одной стороны ненатуральными для человека, не ложащимися на его примитивные понятия о реальности («взял камень, положил в карман» - mov rax, 42), а с другой и не отражают реальность вполне обобщённо (те же split и split_mut отличный пример, в идеальном случае должен был бы быть один split для всего).


не отражают реальность вполне обобщённо (те же split и split_mut отличный пример, в идеальном случае должен был бы быть один split для всего).

Ну ерунду же пишешь. В одном случае ты получаешь срез, удовлетворяющий предикату, с помощью которого можешь пройтись по элементам вектора, а в другом можешь эти элементы еще и изменять. Это две разные задачи. Да, можно оставить один split_mut — типа, не хочешь менять, не меняй, а если хочешь, то меняй. Но это недопустимый подход.

Virtuos86 ★★★★★
()
Ответ на: комментарий от no-such-file

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

Тем не менее, мой опыт показывает несколько другое. Да, в С++ есть перегрузка функций, наследование и т.д. из-за чего теоретически а + б могут приводить к «непредсказуемым» результатам, но на практике это почти никогда не бывает проблемой. Ну и абстракции дают выразительность и дополнительный контекст чего нет у mov rax, 42.

Опять же, если говорить об ансейф в расте: в языках со сборкой мусора ты ведь не боишься внезапных сегфолтов? И спишь спокойно ночью, не смотря на то, что JVM (местами) на С написана. Я, как человек долгое время писавший на С++, не понимаю как можно не видеть пользу явного выделения небезопасного подмножества языка: цель не в том, чтобы выстрелить в ногу было совершенно невозможно, а в том, что подозрительных мест намного меньше. Проще ревьювить, проще вносить изменения.

Ну и позволю и себе немного не подкреплённых опытом рассуждений. Вот ты говоришь, что лисп очень простой, но почему-то тебя не смущает, что там навертеть можно как бы даже не больше: ридер макросы, CLOS, который, вроде как, можно расширять и т.д. Разве это всё не позволяет, при желании, делать всякие неочевидные штуки? На самом деле, мне правда интересно было бы об этом послушать вне контекста данного спора.

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

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

Просто смешно заявлять о «лаконичном и понятном» коде, когда у вас с стандартной библиотеке отдельно split и split_mut и нужно вручную выбрать правильный (т.е. нужно рассуждать о том, о чём по задачам при создания языка хотелось избавится). Кресты и то лучше в этом смысле.

Про «типы как контракт» ты, видимо, не слышал :) unsafe маркирует опасные места. Отрицать, что полезно точно знать, где в программе происходит небезопасный пердолинг байтов или некоторые другие опасные телодвижения, может только идиот.

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

В лиспе единственная киллерфича это работа в образе, которая не имеет почти никакого отношения к особенностям языка, потому что тот же смолток позволяет то же самое, хотя по концепции отличается. Еще в плюс идут хорошие эффективные компиляторы, и то, как писал mv, sbcl уже отстает от гцц, и дальше отставание будет только увеличиваться.

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

Да, раст это низкоуровневый язык.

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

Не понимать, что в низкоуровневом языке пердолинг байтов происходит в каждой строчке, может только идиот. Так что unsafe будет везде, либо его не будет совсем в случае, когда этот идиот пишет очередное веб-говно на расте, хотя нужно было взять пхп.

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

ни один нельзя. раст чемпион по палкам в колеса и надо еще поискать язык где эти палки не были бы так неоправданыш

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

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

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

Для хелловорлда и макрос vec! просто запилить, а чтобы для реального использования был полезен, уже надо подумать. В стдлиб связанный список есть.

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

В лиспе единственная киллерфича это работа в образе

Вот не сказал бы. Основная киллерфича — это замыкания. На них делаются хоть ООП, хоть комбинаторы. В случае Common Lisp ещё специальные переменные: позволяют безопасно и удобно работать с глобальными переменными. А работа в образе лишь чуть облегчает отладку.

sbcl уже отстает от гцц, и дальше отставание будет только увеличиваться

Не уже, а ещё. В смысле, раньше отставал на порядки, теперь в разы. В динамике отставание уменьшается, потому что чем мощнее оптимизационные возможности компилятора, тем менее важна близость языка программирования к ассемблеру.

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

На самом деле, мне правда интересно было бы об этом послушать вне контекста данного

И мне тоже, двумя руками за, как это можно устроить?

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

Разве это всё не позволяет, при желании, делать всякие неочевидные штуки? На самом деле, мне правда интересно было бы об этом послушать вне контекста данного спора.

Переопределение читателя (reader’а) в Common Lisp позволяет читать что угодно как программу на «лиспе».

Типа

(enable-json-syntax)

(defun foobar ()
  ["foo", "bar", 
   {
      "foo": 1,
      "bar": (+ 3 4),
      "baz": w
   }])

В Racket синтаксис переключаемый на уровне модуля

#lang honu

for x in [1, 2, 3] do {
 printf("x ~a\n", x);
}

и

#lang datalog

parent(john, douglas)
    ancestor(A, B) :-
        parent(A, B)
    ancestor(A, B) :-
        parent(A, C),
        ancestor(C, B)

или даже

#lang profj/full
 
class Example {
  static String result = null;
  public static void Main(String[] args) {
    result = "Hi";
  }
}

тоже программы на Racket.

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

И мне тоже, двумя руками за, как это можно устроить?

Создать новую тему? (:

Если повезёт, то набежит народ и начнёт спорить.

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

Racket мне всегда симпатичен был (особенно его типизированный диалект) правда до глубокого изучения так и не добрался. Так понимаю, что как раз и делается акцент на создание DSL.

Но в Racket синтаксис как раз переключается явно и стандартным способом. Так понимаю, что в CL оно менее очевидно. Собственно, я как раз удивлялся почему no-such-file спокойно уживается с тем, что в С++ постоянно «дополнительные раздумья» требуются, а в лиспе всё просто и очевидно. И это при гибкости последнего.

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

Про последнее: угадаешь, чему равен результат

9 же. А код наркоманский.

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

Только реальный код приходится писать, используя чуть больше, чем эти простые принципы.

Так говоришь, будто пишешь/писал реальный код на CL.

turtle_bazon ★★★★★
()
Ответ на: комментарий от no-such-file

Это растопроблемы.

Эти проблемы - продолжение достоинств языка. Скажем, если у нас все данные иммутабельные, то «проблем» ещё меньше, но не всегда это удобно.

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

Создай, с правильным названием, у тебя опыта на форуме побольше будет

У меня нет необходимого опыта, чтобы качественно вбрасывать о лиспе.

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

почему-то тебя не смущает, что там навертеть можно как бы даже не больше: ридер макросы, CLOS, который, вроде как, можно расширять и т.д.

Ридер макросы смущают, поэтому я за очень ограниченное их использование. Да, собственно, пока что какого-то повального увлечения ими у авторов не наблюдается. Потенциал для создания проблем конечно есть, но проблемы пока нет. Возможно это потому что CL непопулярен. Если б он был популярен, то вполне могу допустить что народ устроил бы из этого вакханалию, просто потому что возможно. (Кресты же засрали, даже не имея формальной возможности, когда оказалось что новый весёлый стандарт можно принимать по желанию левой пятки).

Что касается CLOS и т.п. то меня нисколько не смущает, что из простых вещей можно делать сложные. Напротив я за это и выступаю. Но любая абстракция повышающая сложность должна иметь какое-то обоснование, а не просто «мы решили, что так будет лучше». ООП прошло проверку временем и можно сказать, что это хорошая, годная абстракция, которая для человека вполне натуральна и понятна. Я же как бы совсем не против раста или хаскеля, я просто пытаюсь объяснить (себе в т.ч.) почему они не вполне успешны. Эту неуспешность я вижу в том, что сложность их абстракций не востребована. Нет массово таких задач, где она была бы неизбежна, как неизбежен матан в физике, например. Человек всегда выберет что попроще и попонятнее, если не вынужден поступать иначе. Вот и всё.

Далее, я спрашиваю, во-первых а есть ли такие задачи в принципе, пусть не массово, а вообще (т.е. необходим ли раст в программировании, как необходим матан в физике), во-вторых возможно ли создать более удобные для человека абстракции которые бы решали те же задачи, что и раст, например. Пока что я считаю что ответ «нет» на оба вопроса.

no-such-file ★★★★★
()
Ответ на: комментарий от monk

В лиспе единственная киллерфича это работа в образе

Вот не сказал бы. Основная киллерфича — это замыкания. На них делаются хоть ООП, хоть комбинаторы. В случае Common Lisp ещё специальные переменные: позволяют безопасно и удобно работать с глобальными переменными. А работа в образе лишь чуть облегчает отладку.

А вот ты спроси трушных лисперов, лавсана, например, кто из нас более прав :).

sbcl уже отстает от гцц, и дальше отставание будет только увеличиваться

Не уже, а ещё. В смысле, раньше отставал на порядки, теперь в разы. В динамике отставание уменьшается, потому что чем мощнее оптимизационные возможности компилятора, тем менее важна близость языка программирования к ассемблеру.

Я опираюсь на недавно виденные слова mv. Дескать, сбкл ноне в отстающих, ибо в гцц/шланг какую-то фичу прикрутили, которой в лисповом компиляторе нет.

Virtuos86 ★★★★★
()
Ответ на: комментарий от no-such-file

Это две разные задачи

Это растопроблемы.

Это реальность, а не «проблемы», всех языков со строгой статической типизацией (загнул, конечно, тот же хаскель сам выведет тип). Я хз почему ты так упорствуешь в своем невежестве. Ссылка на объект, по которой его можно расковырять, принципиально отличается от ссылки, по которой ты можешь на него только посмотреть. И всё это идет от проработанных концепций заимствования и владения раста. Может быть, синтаксис у раста и корявый, но идеи, которые он выражает, это не какой-то заоблачный матан, как ты пытаешься утверждать.

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от monk

Спасибо, конечно! Но я надеялся, что на примере loop-а ты объяснишь что такое монада вообще. )

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

Я его видел на ЛОР, и из простого там только скобки обычно :)

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

А вот ты спроси трушных лисперов, лавсана, например, кто из нас более прав :).

Ну, ты сказанул))) Ты бы еше Дена73 лиспером назвал. ЛОЛ

Лавсан - крестовик. Или шарпер. Но никак не лиспер - он не чувствует язык, не умеет писать идиоматический код. Хотя, знает гиперспеку и внутренности СБЦЛ.

Аналогия: великолепное знание нотной нотации и умение читать с листа не сделает тебя ни Моцартом, ни Листом.

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

Программирование сильно усложнилось, так что даже один человек редко может что-то дельное написать, нужен коллектив.

Что-то дельное пишет, именно, один человек. Крайне редко - два. А вот довести «что-то дельное» до состояния «продукта» - тут да, нужен коллектив.

Тот же линукс требует труда огромного количества людей, масштабов индустрии.

Прекрасная иллюстрация! Линус написал «дельное» в одиночку за пару месяцев, а потом всем миром, правда под его руководством, доводили до (одного из) индустриального стандарта.

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