LINUX.ORG.RU

Ада: исключения и безопасность

 


2

3

Про Аду еще не забыли?

Известно, что исключения в C++ с одной стороны упрощают обработку нештатных ситуаций, а с другой стороны делают программный код часто сложнее, потому что такой код уже должен поддерживать «гарантии безопасности», что составляет определенную сложность для языка без сборки мусора (GC). Очень много нюансов.

Исключения в Аде появились раньше, чем в C++. Они были уже в стандарте 83-го года. Это была одна из продающихся фишек первого стандарта языка. Как поддержка исключений соотносится с безопасной средой исполнения кода? В Аде есть элементы GC? Там что-то было про подчищение памяти еще в стандарте 83-го года, но я уже давно все забыл.

Гарантируется ли в Аде безопасность на базовом уровне? Не может ли брошенное исключение привести к утечке или какому другому дефекту в памяти? Если нет, то как это соотносится со скоростью исполнения кода?

★★★★★

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

анонимус порадовал. взоржала :)

Чем подтвердили свою репутацию. Хотя в принципе в этом и нет уже особой надобности 😂.

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

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

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

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

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

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

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

репутацию кого?

Единомышленника одиозных персонажей типа царя.

да, я не использую ФП и считаю это дурью, несовместимой с аппаратной частью процессоров.

А кто будет потребности рынка удовлетворять? Как минимум, веб на указателях писать не найдешь хацкеров. То что в вашей рабочей области рулит Си/Си++, не повод думать, что этого хватит для всего и для всех.

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

Чем подтвердили свою репутацию. Хотя в принципе в этом и нет уже особой надобности 😂

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

Даешь Растическую Революцию! Мы здесь Раст!

Разорванный Флакон

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

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

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

говнокод и его проблемы - с этим не ко мне

Какой говнокод?

и да, я не вижу ничего плохого в поддержке царя (хотя и не всегда)

чтд

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

Тем не менее, плюшки ФП реализованы в расте как zero-cost abstractions. Так что, процессору ни холодно, ни жарко от того, есть в расте возможности ФП или нет, но зато самому программисту очень даже хорошо от этого.

Я так понимаю, что ты просто не знакома с языком, как и многие фанбои других языков. Впрочем, фанбои раста тоже не всегда знакомы с теми же плюсами. Адын-адын.

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

я не фанат плюсов. в смысле, того, во что их превратили за последние года три. до 2011 стандарта они были вполне вменяемы, а потом понеслось. в последние годы я пишу в основном на C, иногда ассемблером балуюсь.

конечно, в плюсах можно не использовать весь жир и синтаксический сахар, но сам факт заговнения стандарта неприятен.

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

А кто будет потребности рынка удовлетворять?

ПХП. Уже 20 лет удовлетворяют без ФП-соплей.

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

Ты оптимист.

А что делать? ;)

Вроде как после фиксации черновика C++20 нескольким направлениям развития C++ обещали дать больший приоритет, в том числе и паттерн-матчингу.

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

eao197 ★★★★★
()
Ответ на: комментарий от deep-purple

строить бизнес-логику на исключениях = называться долбаёбом

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

Ну, c++11 и все последующие стандарты мне видятся больше как работа над ошибками. По-моему очень важно, что там ввели move-семантику. Правда, она сложнее получилась для понимания, чем в том же расте. Растоман, скорее всего, даже не задумается о деталях реализации move, хотя в расте этот move вездесущий, и он крайне важен для эффективного исполнения. В c++ же нужно еще почесать репу перед использованием move.

С++ часто обвиняли в том, что обычно программы на нем исполнялись медленнее, чем написанные на сях. Мне кажется, что move-семантика как раз помогает плюсистам уменьшить эту разницу, если не свести к нулю.

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

Ага, растоманы не дают спать спокойно коммитетчикам c++, подгоняют и с этой стороны тоже. В с++ вынуждены будут ввести паттерн-матчинг, чтобы сохранить лояльность программистов.

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

JS-портянки вне хипстерких сайтов с ФП не имеют ничего общего

Ржавые портянки вне парты тоже. И даже хацкельные портянки. Только более каноничные ФП-языки требуют больше усилий от программиста для борьбы с ФП-фантазиями. Поэтому жс в каждом утюге, раст в следовых количествах, а хацкеля на рынке вообще нет.

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

ну вот я там пример давал бизнес логики - откат транзакции в бд.

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

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

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

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

deep-purple ★★★★★
()
Ответ на: комментарий от dave

С чего вы взяли, что в этом виноваты растоманы?

В с++ вынуждены будут ввести паттерн-матчинг, чтобы сохранить лояльность программистов.

Ну да, это вовсе не потому, что паттерн-матчинг уже вполне пригоден для широкого использования в мейнстриме и с ним сейчас знакомы гораздо больше людей, чем 25-30-35 лет назад. И не потому, что в C++ sum-types уже представлены в стандартной библиотеке.

Это потому, что лояльность нужно сохранить.

Ну OK, чё. Лишп головного мозга во все поля.

eao197 ★★★★★
()
Ответ на: комментарий от deep-purple

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

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

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

А зря ёрничаешь и недооцениваешь. Ладно, хватит с меня. Тема закрыта.

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

Заметь, что structured bindings из C++17 уже немного похожи на тупой паттерн-матчинг. А вообще, он действительно сейчас везде, даже в C#, а ведь Саттер говорил о некотором влиянии Хейлсберга на плюсы.

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

да, там есть буквально 2-3 полезных изменения. остальное - дикое фуфло. и замусоривание стандарта мне не нравится. мне не нравится также втаскивание чисто системных вещей (вроде потоков) в язык. это ненормально, потому что это не языко-зависимые, а чисто архитектурные вещи. ну и много другой дурости и откровенного синтаксического сахара. в общем, мне плюсы стали нравиться всё меньше. какой-то понос бешеного принтера стандартов там завёлся и они всё никак не могут успокоиться.

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

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

Iron_Bug ★★★★★
()
Ответ на: комментарий от deep-purple

Конечно, они для обработки исключительных ситуаций.

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

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

58 лет, Карл! 1962 год!

SNOBOL («StriNg Oriented and symBOlic Language») is a series of programming languages developed between 1962 and 1967 at AT&T Bell Laboratories by David J. Farber, Ralph E. Griswold and Ivan P. Polonsky, culminating in SNOBOL4. It was one of a number of text-string-oriented languages developed during the 1950s and 1960s; others included COMIT and TRAC.

SNOBOL4 stands apart from most programming languages of its era by having patterns as a first-class data type (i.e. a data type whose values can be manipulated in all ways permitted to any other data type in the programming language) and by providing operators for pattern concatenation and alternation. SNOBOL4 patterns are a type of object and admit various manipulations, much like later object-oriented languages such as JavaScript whose patterns are known as regular expressions. In addition SNOBOL4 strings generated during execution can be treated as programs and either interpreted or compiled and executed (as in the eval function of other languages).

SNOBOL4 was quite widely taught in larger US universities in the late 1960s and early 1970s and was widely used in the 1970s and 1980s as a text manipulation language in the humanities.

более эффективной реализацией был SPITBOL, который примерно тоже самое.

SPITBOL был реализован как MINIMAL, минимальная виртуальная машина на макроассемблере.

получилась очень эффективная реализация. потом в 70-х, кажется Пайк написал диплом или диссер по реализации ассемблера на SPITBOL MINIMAL (типа как у Кена Томпсона была реализация ассемблера на awk).

вообще, эти языки похожи: SNOBOL/SPITBOL и Icon/Unicon/Object Icon.

тем, что в Icon/Unicon/Object Icon fisrt class objects/datatypes – это выражения и ковыражения. то есть, генераторы как в питоне которые вычисляются лениво, продолжения и замыкания, если по-простому. futures, вот это всё.

далее Icon/Unicon/… – это goal-oriented язык. то есть, цепочка вычислений/монада/«бизнес-логика из ретурнов, обмазанная сахарным сиропом», лол – это последовательность вычислений, невозбранно приближающаяся к цели.

последовательность успехов и возврат multiple values (success, значения, продолжения) / vs. прерывание цепочки вычислений по неуспеху. среди ковыражений-генераторов.

а в SNOBOL/SPITBOL тоже самое только гораздо проще. SNOBOL: это ассемблер/макроассемблер, у которого есть метки, выражения (присваивание или паттерн матчинг) и ТРИ перехода-продолжения. в случае успеха (матчинга), неуспеха или по-любому.

и это всё – эффективная реализация начиная с 1962 года.

шёл уже 58-й год, Карл!

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

шёл уже 58-й год, Карл!

Не выдумывай, ононим. Паттерн-маттчинг был придуман специально для языка Rust™, и все остальные языки ему завидуют.

Разорванный Флакон

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

The implementation of MACRO SPITBOL is written in three languages: MINIMAL, C, and assembler.

The SPITBOL compiler and runtime is written in MINIMAL, a machine-independent portable assembly language.

The runtime is augmented by procedures written in C that collectively comprise OSINT (Operating System INTerface). These procedures provides such functions as input and output, system initialization and termination, management of UNIX pipes, the loading of external functions, and so forth.

The implementation also includes assembly code. This size of this code varies according to the target machine. About 1500 lines are needed for the x86 architecture running UNIX. This code provides such functions as macros that define the translation of MINIMAL instructions that take more than a few machine-level instructions, support for calling C procedures from MINIMAL, for calling MINIMAL procedures from C, for creating save files and load modules, and for resuming execution from save files or loand load modules.

To give some idea of the flavor of the code, consider the following simple SPITBOL program that copies standard input to standard output.

loop output = input :s(loop)
end

By default, the variable input is input-associated to standard input, so each attempt to get its value results in reading in a line from standard input and returning the line as a string. The read fails if there are no more lines, and succeeds otherwise.

Similarly, the variable output is output-associated with standard output, so each assignment to output causes the assigned value to be written to the standard output file.

The osint procedure for writing a line is SYSOU. It is called from within SPITBOL as part of assignment, as shown in the follwing excerpt from the MINIMAL source:

*      here for output association

asg10  bze  kvoup,asg07      ignore output assoc if output off
asg1b  mov  xr,xl            copy trblk pointer
       mov  trnxt(XR),xr     point to next trblk
       beq  (XR),=b_trt,asg1b loop back if another trblk
       mov  xl,xr            else point back to last trblk
.if    .cnbf
       mov  trval(XR),-(XS)  stack value to output
.else
       mov  trval(XR),xr     get value to output
       beq  (XR),=b_bct,asg11 branch if buffer
       mov  xr,-(XS)         stack value to output
.fi
       JSR  gtstg            convert to string
       PPM  asg12            get datatype name if unconvertible

*      merge with string or buffer to output in xr

asg11  mov  trfpt(XL),wa     FCBLK ptr
       bze  wa,asg13         jump if standard output file

*      here for output to file

asg1a  JSR  sysou            call system output routine
       err  206,output caused file overflow
       err  207,output caused non-recoverable error
       exi                   else all done, return to caller
anonymous
()
Ответ на: комментарий от anonymous

From the OSINT C code (the C procedure name starts with ‘z’ since there is some needed intermediate code (shown below) to go from MINIMAL to C at runtime):

zysou()
{
    REGISTER struct FCBLK *fcb = WA(struct FCBLK *);
    REGISTER union block *blk = XR(union block *);
    int result;

    if (blk->scb.typ == type_scl) {
	/* called with string, get length from SCBLK */
	SET_WA(blk->scb.len);
    } else {
	/* called with buffer, get length from BCBLK, and treat BSBLK
	 * like an SCBLK
	 */
	SET_WA(blk->bcb.len);
	SET_XR(blk->bcb.bcbuf);
    }

    if (fcb == (struct FCBLK *) 0 || fcb == (struct FCBLK *) 1) {
	if (!fcb)
	    result = zyspi();
	else
	    result = zyspr();
	if (result == EXI_0)
	    return EXI_0;
	else
	    return EXI_2;
    }

    /* ensure iob is open, fail if unsuccessful */
    if (!(MK_MP(fcb->iob, struct ioblk *)->flg1 & IO_OPN)) {
	 return EXI_1;
    }

    /* write the data, fail if unsuccessful */
    if (oswrite
	(fcb->mode, fcb->rsz, WA(word), MK_MP(fcb->iob, struct ioblk *),
	 XR(struct scblk *)) != 0)
	 return EXI_2;

    /* normal return */
    return EXI_0;
}

Here is a fragment of the assembly code that is used to call a C procedure from MINIMAL. The code is for 32-bit X86 and is written using NASM (Netwide Assembler) syntax.

	%macro	mtoc	1
	extern	%1
	; save minimal registers to make their values available to called procedure
	mov     dword [reg_wa],ecx
        mov     dword [reg_wb],ebx
        mov     dword [reg_wc],edx	; (also reg_ia)
        mov     dword [reg_xr],edi
        mov     dword [reg_xl],esi
        mov     dword [reg_cp],ebp	; Needed in image saved by SYSXI
        call    %1			; call c interface function
;       restore minimal registers since called procedure  may have changed them
        mov     ecx, dword [reg_wa]	; restore registers
        mov     ebx, dword [reg_wb]
        mov     edx, dword [reg_wc]	; (also reg_ia)
        mov     edi, dword [reg_xr]
        mov     esi, dword [reg_xl]
        mov     ebp, dword [reg_cp]
;	restore direction flag in (the unlikely) case that it was changed
        cld
;	note that the called procedure must return exi action in eax
	ret
	%endmacro

  ...

	global	sysou			; output record
sysou:
	mtoc	zysou

The remainder of this document consists of text that was formerly part of the source code for the MACRO SPITBOL compiler. It was converted from plain text to HTML by Dave Shields.

MINIMAL – Machine Independent Macro Assembly Language

The following sections describe the implementation language originally developed for SPITBOL but now more widely used. MINIMAL (Machine Independent Macro Assembly Language) is an assembly language for an idealized machine. The following describes the basic characteristics of this machine.

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

и т.д. и т.п.

например, в большинстве реализаций SPITBOL поддерживаются загружаемые функции (на dll, so, на Cи или asm); большое количество встроенных функций, например сокеты ( tcp/ip клиент/сервер, например irc бот в пару строчек) и т.п.

выглядит как продвинутый макроассемблер на паттерн-матчинге. основая суть –

метка выражение :s(переход_SUCCESS) f:(переход_FAIL) :(переход_по_любому)

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

паттерн матчинг в v3 был только по строкам, в SNOBOL4 и выше (и SPITBOL) – появились пользвательские АDT

например, можно строить деревья. есть GC.

в общем, SNOBOL это такой продвинутый типа awk. но

1)с паттерн матчингом

2)произвольные структуры данных, например, деревья

3)можно определять свои функции на всём этом

4)подгружать из dll/so

5)стандартная библиотека достаточно фичаста.

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

ELIZA.SPT 1/4

из spitbol-88-binary-master spitbol-88-source:

*	ELIZA in SNOBOL4
*
*	The original ELIZA was written by Professor Joseph Weizenbaum in
*	FORTRAN with the SLIP list processing extensions.  The first
*	article describing ELIZA was published in Vol 9, No. 1 (Jan., 1966)
*	of the Communications of the ACM (pp.36-45).  It was recast in SNOBOL4
*	by Robert Duquet to provide a shorter and simpler program for an
*	introductory course in artificial intelligence.  His description of
*	this package appears in SIGPLAN Notices, Vol 5, No. 12 (Dec., 1970),
*	(pp. 50-60), and is included here in file ELIZA.txt.
*
*	Later extensions made to ELIZA are not included here.  Consult
*	CONTEXTUAL UNDERSTANDING BY COMPUTERS, Communications of the ACM,
*	Volume 10, No. 8 (August 1967  (474-480)
*
*	Note: This program decomposes the script using blanks for white space.
*		Don't use tabs in any modifications you make to the script
*		 without changing the program appropriately.
*
	&ANCHOR	=	1
	&TRIM	=	1
	UPPERS.	= 	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	LOWERS.	=	"abcdefghijklmnopqrstuvwxyz"

	PRE.TRIM =	SPAN(' ') | NULL
	P.0	=	*KEY.
	P.1	=	PRE.TRIM BREAK(' ') . WORD. ' '
	P.2	=	POS(0) RTAB(1) '/'
	P.3	=	BREAK(':') . CONTENT. ':'
	P.4	=	PRE.TRIM REM . CONTENT.
	P.5	=	PRE.TRIM ANY('SLD') . WORD. ' '
	SHORTEN. =	BREAK('.,?') . PHRASE. ANY('.,?') REM . TRAILER.
	X.REF	=	PRE.TRIM 'CF'
	BUMP.	=	PRE.TRIM 'NEWKEY'
	PAREN.	=	PRE.TRIM '/' BREAK('/') . CONTENT. '/'
	STASH.	=	PRE.TRIM '/' BREAK('/') . *$STORE. '/'
	CALL.TO.SNOBOL	=  PRE.TRIM 'SNOBOL'
	LAST.SCRIPT	=  PRE.TRIM 'END'
	ATTENTION.	=  PRE.TRIM '*'

	INTRODUCTION	=  'HOW DO YOU DO.'
	CLUELESS	=  "VERY INTERESTING:I'M NOT SURE I UNDERSTAND YOU FULLY:"
+			   "PLEASE GO ON:WHAT DOES THAT SUGGEST TO YOU:"
+			   "DO YOU FEEL STRONGLY ABOUT DISCUSSING SUCH THINGS?:"
	RETAIN		=  'MY'
	GOODBYE		=
	KEYWORDS. 	=  '.'

* We now read the script(s) and form strings as follows:
* For each key word 'XXXX' we form the following variables:
*	S.XXXX		is a substitute word.   (Optional)
*	L.XXXX		is a level number (if absent, key is ignored)
*	N.XXXX		a count of the number of decompositions
*	D.I.XXXX	is the I'th decomposition pattern
*	R.I.XXXX	is a string of recomposition rules for the I'th
*			decomposition.  Rules are separated by ':'.
*

	INPUT(.SFILE, 2, "eliza.scr") 			:S(HIGGINS)
	OUTPUT	=	'Cannot open script "eliza.scr"'	:(END)

HIGGINS	SCRIPT. =	SFILE				:F(START)
	SCRIPT. ? ATTENTION. =				:S(FLAG)

anonymous
()
Ответ на: ELIZA.SPT 1/4 от anonymous

* Get keyword on beginning of line to WORD.
	SCRIPT. ? P.1 =					:F(HIGGINS)
	KEY.	=	'.' WORD.

* If it is not already defined, append it to the KEYWORDS. list
	KEYWORDS. ? P.0					:S(LESSON)
	KEYWORDS. = KEY. KEYWORDS.

* Look for S, L or D command, store command in WORD. and branch indirect.
LESSON	SCRIPT. ? P.5 =					:F(HIGGINS)S($WORD.)
ERR	OUTPUT	=	'SCRIPT ERROR: ' WORD. ' ' SCRIPT.	:(HIGGINS)

* Substitute word.  Create indirect pointer to S.XXXX, then fetch the
*  substitute and stash it away.
S	STORE.	=	'S' KEY.
	SCRIPT.	? STASH.	=			:F(ERR)S(LESSON)

* Keyword level number.  Get number to CONTENT and store in L.XXXX
L	SCRIPT. ? PAREN.	=			:F(ERR)
	$('L' KEY.)	=  INTEGER(CONTENT.) +CONTENT.	:(LESSON)

* Decomposition rule.  Increment (possibly creating) N.XXXX for number
* of rules seen so far for this keyword.  Keep around in temp N.N
D	N.N	=	$('N' KEY.) + 1
	$('N' KEY.)	=	N.N

* Get the decomposition rule:
	SCRIPT. ? PAREN.  =				:F(ERR)

* Is it a SNOBOL4 pattern or just text substitution?
	CONTENT. ? CALL.TO.SNOBOL =			:S(SPECIAL)

* Define this rule as D.i.XXXX = ARB <rule> REM . POST
*  Most recompositions simply use the text following the matching
*   decomposition, and REM . POST will isolate it later.
	$('D.' N.N KEY.)	=	ARB CONTENT. REM . POST

* Now get all the recomposition rules for this particular decomposition.
*  They will be stored as a long string separated by ':'s, with name R.i.XXXX
RULES	STORE.	=	'R.' N.N KEY.

* Store away the first one if it is on the same line as the D /.../ rule.
	$STORE.	=	DIFFER(SCRIPT.) SCRIPT.		:F(NEW.LINE)

* Keep reading recomposition strings until a '/' appears at the end of line
LOOP	$STORE.	? P.2					:S(HIGGINS)

NEW.LINE $STORE. = $STORE. SFILE			:F(NEXTS)S(LOOP)

* The following are special script-handling statements

* This decomposition rule is an explicit SNOBOL4 statement.
SPECIAL	$('D.' N.N KEY.)	=	EVAL(CONTENT.)	:(RULES)

ENCODE	SCRIPT.	=	CODE(SCRIPT. ' :(HIGGINS);')	:S<SCRIPT.>
	OUTPUT	=	&ERRTEXT SCRIPT.		:(HIGGINS)	

* This script line is an explicit call to SNOBOL4.
FLAG	SCRIPT. ? CALL.TO.SNOBOL =			:S(ENCODE)

* Check for the end-of-script line.
	SCRIPT. ? LAST.SCRIPT				:S(START)
	OUTPUT	=	'Illegal special statement: ' SCRIPT.	:(HIGGINS)

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

* We now hold a conversation.  First, we read a sentence, and
*  search for key words replacing appropriate ones and stacking the
*   keys in a quasi-ordered list (strings).  If a keyword is found with
*    a higher level number than any seen so far, it is prepended to the
*     string CUES., otherwise it is appended.

START	ENDFILE(2)
	OUTPUT	=	INTRODUCTION

* Read an input line, and convert to upper case
HEAR	PHRASE.	=	REPLACE(INPUT,LOWERS.,UPPERS.) '.'	:F(END)

* Break apart at any punctuation into PHRASE. and TRAILER.
HEARLESS PHRASE. ? SHORTEN.

* Append a blank to make word matching easier.
	PHRASE.	=	PHRASE. ' '

* COPY. will contain the input sentence after any substitutions
	COPY.	=

* CUES. will act as a stack of keywords encountered.
	CUES.	=

* Initialize for highest keyword level seen so far.
	CUE.LEVEL	=	0

SPLIT	&ANCHOR	=	1

* Get next input word to WORD., and remove from PHRASE.  If no more words,
*  go form a reply.
	PHRASE.	? P.1	=				:F(REPLY)
	&ANCHOR	=	0

* Is it a keyword?
	KEYWORDS. ? WORD.				:F(KEEP)

* Keyword found.  If there is a substitute, use it.
	NEW.WORD	=	DIFFER($('S.' WORD.))
+				$('S.' WORD.)		:S(REPLACE)

* Otherwise append to copy without substitution.
	COPY.	=	COPY. WORD. ' '			:(STACK)

REPLACE	COPY.	=	COPY. NEW.WORD ' '

* Put the keyword correctly on the stack if it has an associated level number
STACK	NEW.LEVEL	=	DIFFER($('L.' WORD.))
+				$('L.' WORD.)		:F(SPLIT)
	CUE.LEVEL	=	GT(NEW.LEVEL, CUE.LEVEL)
+				NEW.LEVEL		:F(LOCUE)
* High priority.  Put on top of stack.
	CUES.	=	WORD. ':' CUES.			:(SPLIT)

* Low priority.  Put on end of stack.
LOCUE	CUES.	=	CUES. WORD. ':'			:(SPLIT)

* Here if it wasn't a keyword.  Just append it to the copy.
KEEP	COPY.	=	COPY. WORD. ' '			:(SPLIT)
anonymous
()
Ответ на: комментарий от anonymous

*
* This part forms our reply to the input sentence after searching for keywords.
*
* Pop the top keyword from the stack to CONTENT.
REPLY	CUES. ? P.3	=				:F(NOCUE)

* Create .XXXX in CUE.
NEXTCUE	CUE.	=	'.' CONTENT.
	N.N	=	0

* Get number of decomposition rules associated with this keyword to NMAX.
	NMAX.	=	$('N' CUE.)

* Index through the rules with N.N.
ANALYSE	N.N	=	LT(N.N, NMAX.) N.N + 1		:F(NOCUE)

* Apply next decomposition rule to COPY.  Loop if no match.
	COPY. ? $('D.' N.N CUE.)			:F(ANALYSE)

* This keyword found in COPY.  Get the current top recomposition rule from
* the circular list in R.i.XXXX to CONTENT.
	$('R.' N.N CUE.) P.3 =

* House keep stray '/' from original input script.
	CONTENT. ? '/'	=

* Maintain circular list by putting current recomp rule on end of R.i.XXXX
	$('R.' N.N CUE.) = $('R.' N.N CUE.) CONTENT. ':'

* Does this recomp rule say we should CF another keyword?
	CONTENT. ? X.REF	=			:S(NEWCUE)

* Does recomp rule say we should pop the CUES stack and try another keyword?
	CONTENT. ? BUMP.				:S(REPLY)

* Just evaluate the recomposition rule to produce the reply.  What could be
*  simpler?
	OUTPUT	=	'.. ' EVAL(CONTENT.)

* Check for end of dialogue variable getting set in script
	DIFFER(GOODBYE)					:S(END)

* Is the keyword a special one to say we should retain the COPY for later use
*  in case we get stuck?
	MEMORY.	=	IDENT(CUE., '.' RETAIN)
+			LT(SIZE(MEMORY.),200)
+			MEMORY. COPY. ':'		:(HEAR)

* Here if recomp rule said to CF another keyword.  Get the new keyword to
*  CONTENT, and go apply its decomposition rules.
NEWCUE	CONTENT. P.4					:(NEXTCUE)

* This is what we do if there are no key words in the input.
*
* If the input consisted of several punctuation separated phrases, discard
*  the current phrase and try the next one.
NOCUE	PHRASE.	=	DIFFER(TRAILER.) TRAILER.	:S(HEARLESS)

* That didn't work.  Can we dredge up something from our memory?
	MEMORY. ? P.3	=				:F(ER.AH.UM)
	OUTPUT	=	'.. EARLIER YOU SAID ' CONTENT.	:(HEAR)

* Out of ideas.  Give next lame response and shift CLUELESS circularly.
ER.AH.UM CLUELESS ? P.3	=
	CLUELESS = CLUELESS CONTENT. ':'
	OUTPUT = CONTENT.				:(HEAR)

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

eliza.scr и прочие демки

eliza.scr – лог чата с чатботом Элизой

описание

Eliza на SNOBOL4

ATN.SPT – исходники парсера/компилятора Augmented Transition Network Language

из «бизнес-логики» (лолъ) типа такой ATN.IN строится парсер на естественном языке примера:

 SENTENCES S1
    A BIG RED BLOCK WAS DROPPED BY THE BOY ;
    THE BOY DROPPED A BIG RED BLOCK ;
    A BLOCK WAS DROPPED ;
    THE BLOCK DROPPED ;
 END S1

(этот же пример есть в книжке aisnobol.zip, среди прочих)

далее в сорцах – подключение dll/so на C/asm, tcp сокеты клиент/сервер, и прочее тому подобное.

см. также реализации spitbol-88, spitbol-360(на ассемблере OS/360), spitbol-go (c MINIMAL машиной реализованной на Go), spitbol-windows-nt, дос реализации (с вызовом dll/so на asm/c), csnobol реализацию, spitbol реализацию

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

в общем, SNOBOL/SPITBOL занятный недоязычок. и практически полезный.

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

это похоже на этот ваш Result с std::variant или как там его. ну то есть, эти вот самые «континуации» как в книжке у Столярова – продолжения, то есть.

причём в силу ассемблерности этого SNOBOL/SPITBOL/как там его, там врукопашную задаются просто метки. для выхода из определения функции, для перехода если успех в одно место, если неуспех – в другое. и по любому, в третье.

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

паттерн матчинг реализован вычислением «выражений» с ARB, ANY, SPAN и прочими «псевдо» функциями. в том смысле псевдо, что это выражение матчится ну примерно как кусок БНФ.

или похоже на PEG парсер.

Ada тут кстати при том, что далее реализация подобных «выражений» в духе SNOBOL/SPITBOL (разница между ними не существенна – немного другой набор функций).

существует во многих языках. например, Lua. или та же Ada: пакет GNAT.Spitbol (вообще в GNAT.* много чего полезного реализовано).

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

внизу на http://www.snobol4.org/ в Implementations & Tools – реализации снобол выражений в lua, js, питоне, C/C++, Ada95, Java, форте и т.п.

есть препроцессор snocone

hardbol/spitbol – spitbol-linux с реализацией на ассемблере. какой машины? да как бы не этой вот MINIMAL.

ооп и полиморфизм в сноболе.

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

вообще того же Столярова про континуации (итить) можно почитать на тему того, как этот Result из успехов и неудач вполне себе успешно заменяет исключения.

а снобол/спитбол/icon/unicon – на тему того. как на этом может быть выстроен весь язык, вся его goal-oriented парадигма.

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

Гарантируется ли в Аде безопасность на базовом уровне? Не может ли брошенное исключение привести к утечке или какому другому дефекту в памяти?

там в общем нужно читать про управляемые переменные (controlled), limited типы и прочее.

про исключения. есть несколько профилей. в базовом нужен хотя бы минималистичный стектрейс. может быть ограниченный профиль типа Ravenscar. где гарантируется определённое ограниченное поведение.

нужно читать книжки про примеры, где может встретиться как написать свой рантайм, свой профиль, портировать на новый микроконтроллер по готовому BSP. например. или описание GNAT рантайма, есть занятная книжка про потроха GCC/GNAT.

если коротко, там описано как рантайм запускает исключения, объектную систему, задачи. с учётом того что задач может быть несколько. по сути компилятор GNAT транслирует аду в си-подобное представление вроде GIMPLE/RTL TreeSSA и прочее. и далее гарантирует, что таски, задачи – транслируются в параллельные процессы, которые запускает рантайм. синхронизированные через рандеву. далее нагенерированное оптимизируется бекендом GCC компилятора. где-то здесь посередине возникает код, похожий на тот, который ты написал бы руками для С/С++. только сгенерированный Ада компилятором.

ещё можно читать исходники альтернативных рантаймов, например drake. и альтернативных профилей, например Ravenscar. чтобы понять какие именно гарантии ожидаются от рантайма в профиле для уровней поддержки реализации исключений. там вроде как их несколько. то есть, хотя бы распечатать стектрейс и сдохнуть. без рекурсии, перевыбрасывания исключения, структурных исключений. в минималистичном профиле. в нормальном – более полноценные.

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

ещё можно смотреть на adalib learn или как там pdf с книжками. про примеры и истории успеха. там было про портирование рантайма на новое железо. на pebble какой-то. или новый микроконтроллер.

ещё там был пример про тетрис на SPARK. про контрактное программирование и функциональные спецификации на SPARK. вот это вот всё.

в общем, занятно чтиво бывает.

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

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

какой-то набор парадигм.

в этом смысле вычисление на монадах и АДТ, Result, этот вот такой продвинутый паттерн матчинг в духе SNOBOL/SPITBOL и последовательность вычислений goal-oriented как последовательность успехов и неудач

– и до кучи, «континуации» туда же (с примерами от Столярова)

— это примеры того, как могут быть организованы вычисления/исключения/стратегии обработки ошибок, contidions & restarts в нормальном языке.

здесь, и С++ и Ада – вроде бы языки, которые поддерживают и не запрещают (уже хорошо) такую парадигму.

но синтаксический мусор в духе шаблонов делает ей неудобно. и таки неправильно.

в этом смысле ада – с более разумным набором парадигм/фич по умолчанию. с более разумным человекочитаемым синтаксисом.

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

а ненужные фичи ограничить прагмами. и получить нечто контролируемое. паскалеподобное.

vs подхода от С++32 С++10500. и новых стандартов от комитетчиков.

с неудобным синтаксисом, в духе концептов. или шаблонов, укушенных александреску.

ну то есть, вроде бы ++ не запрещает АДТ моноидальную goal-oriented парадигму на монадах и «континуациях».

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

но гораздо не читаемее чем в аде.

или, сноболе вот. или icon/unicon/object icon.

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

SENTENC.SPT: Dick walks with Jane. и ЕЯ-программинг.

*	(c) COPYRIGHT 1985, 1994 - CATSPAW, INCORPORATED
*	ALL RIGHTS RESERVED.
*	USE OF THIS SOURCE CODE IS GOVERNED BY A BSD-STYLE
*	LICENSE THAT CAN BE FOUND IN THE LICENSE FILE.

*	Sentence.spt
*
*	This progam defines a simple sentence grammar, and then
*	accepts sentences from the keyboard to see if they can be
*	matched by the grammar.
*
*	You'll have to examine the program to see the words that
*	it recognizes.  Try it with sentences like:
*
*	Dick walks with Jane.
*	Zippy eats the yellow banana slowly.
*	The aggressive monkey reads the large book, however, Dick is a boy.
*
*	Contributed by Prof. Michael Feldman, George Washington Univ.

	&TRACE = 500
	&TRIM = 1
	UPPERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	LOWERS = "abcdefghijklmnopqrstuvwxyz"

	BL = SPAN(' ')

	NOUN = (  'BOY' | 'GIRL' | 'MONKEY' | 'TREE' | 'SCHOOL' | 'BOOK'
+			| 'BANANA' ) $ NOM
	TRACE('NOM')

	ARTICLE = ( 'A' | 'THE' ) $ ART
	TRACE('ART')

	CONJUNCTION =  ( 'AND' | 'BUT' | 'HOWEVER' ) $ CONJ
	TRACE('CONJ')

	PROPER = ( 'DICK' | 'JANE' | 'ZIPPY' ) $ PROP
	TRACE('PROP')

	PRONOUN = ( 'HE' | 'SHE' | 'IT' ) $ PRON
	TRACE('PRON')

	ADJECTIVE = ( 'LARGE' | 'SMALL' | 'GRAY' | 'YELLOW'
+			| 'NICE' | 'AGGRESSIVE' ) $ ADJ
	TRACE('ADJ')

	ADVERB = ( 'SLOWLY' | 'ENTHUSIASTICALLY' ) $ ADV
	TRACE('ADV')

	TRANSITIVE = ( 'READS' | 'GIVES' | 'EATS' | 'WRITES' ) $ TRANS
	TRACE('TRANS')

anonymous
()
Ответ на: SENTENC.SPT: Dick walks with Jane. и ЕЯ-программинг. от anonymous

	INTRANSITIVE = ( 'RUNS' | 'WALKS' ) $ INTRANS
	TRACE('INTRANS')

	BEING = ( 'IS' | 'WAS' ) $ BE
	TRACE('BE')

	PREPOSITION = ( 'TO' | 'FROM' | 'WITH' ) $ PREP
	TRACE('PREP')

	NOUN.PHRASE = ( *PROPER | (*ARTICLE *BL *NOUN)
+			| (*ARTICLE *BL *ADJECTIVE *BL *NOUN) ) $ NP
	TRACE('NP')

	PREP.PHRASE = ( *PREPOSITION *BL *NOUN.PHRASE ) $ PP
	TRACE('PP')

	VERB.PHRASE = ( (*INTRANSITIVE *BL *PREP.PHRASE)
+			| (*TRANSITIVE *BL *NOUN.PHRASE *BL *PREP.PHRASE)
+			| (*TRANSITIVE *BL *NOUN.PHRASE)
+			| (*BEING *BL *NOUN.PHRASE)
+			| *INTRANSITIVE | *BEING ) $ VP
	TRACE('VP')

	PREDICATE = ( (*VERB.PHRASE *BL *ADVERB)
+			| *VERB.PHRASE  ) $ PRED
	TRACE('PRED')

	SUBJECT = ( *PRONOUN | *NOUN.PHRASE ) $ SUBJ
	TRACE('SUBJ')

	CLAUSE = ( *SUBJECT *BL *PREDICATE ) $ CL
	TRACE('CL')

	SENTENCE = POS(0) ( *CLAUSE
+		ARBNO( *BL *CONJUNCTION *BL *CLAUSE ) )
+ 		$ SENT (*BL | "") RPOS(0)
	TRACE('SENT')

READ	S = INPUT						:F(END)
	OUTPUT = '-----------------------------------------------'
	OUTPUT = S
	OUTPUT = '-----------------------------------------------'
	REPLACE(S,LOWERS ",.-!?;:",UPPERS "       ") ? SENTENCE	:S(YES)F(NO)
YES	OUTPUT = '==>SENTENCE FOUND'			:(READ)
NO	OUTPUT = 'NO' 					:(READ)
END

anonymous
()
Ответ на: ELIZA.SPT 1/4 от anonymous

снобололисп

test.spt где-то там: лисп, реализованный на сноболе

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

в Аде, в прошлом конкуренте С++, некогда самом реальном конкуренте С++ из всех существующих

Ада никогда не была конкурентом C++. У них очень разные нишы. На языке ада писали там, где безопасность превыше всего. Например, военные. И на все твои вопросы про гарантии безопасности в аде, ответ «да, безопасно».

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

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

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

Ну, обычная практика, что в языках с GC на финализатор ставят освобождение ресурса

Обычно в языках с GC нет финализаторов, а опыт Java показал, что это плохая практика, и финализаторы там не рекомендованы к использованию.

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