LINUX.ORG.RU

язычок вот написал

 


1

1

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

пример теста(форматирование частично слетело, как уж есть):

//some tests fot compiler
definition Tests
	fun testAll()
end Tests

//##########################
module Tests
	import
		SYSTEM
		Strings
		Con = Console
		IO
		Suite = TestHelper

	alias
		assert	= TestHelper.assert
		error		= TestHelper.error
		write		= Con.write
		writeLn	= Con.writeLn
		writeInt= Con.writeDec
		OK 			= TestHelper.ok


//test type constructors
	type
		WeekDay			= enum (one,two,three)
		Colors 			= enum (White, Red, Blue, Green, Black)
		Record2d 		= record var _x,_y:int end
		SetOfColors = setof (Colors)
		FuncType  	= fun		(int,int):int

//############
	var //global vars
		Res:int
		lint:int

//###########################
	//func OK() {	Con.writeLn("..OK")	}

	fun testLocalPointer():bool {
		const Val = 777;
		let lx=0;
		var lp:^int = addr(lx);

		lp^=Val;
		return lx==Val
	}

	fun testEnum():bool {
		const	cc = WeekDay.two
		var		lday:WeekDay=WeekDay.two;

		write("testEnum..")
		case lday
		of WeekDay.two	:	return true
		else error("wrong case selected 1")
		..

		case lday
		of cc	:	return true
		else error("wrong case selected 2")
		..

		return false
	}

	fun testArray():bool {
		return true
	}

	fun testRecord():bool {
		return true
	}

	fun testTypes(){
		Suite.test(testLocalPointer, "testLocalPointer")
		Suite.test(testEnum,"test enum")
		Suite.test(testArray,"test array")
		Suite.test(testRecord,"test record")
	}

//###############################
//test statemens
//###############################
	fun testRepeat(fx:int) {
		write("Test repeat...")
		repeat
			if fx%100==0 { write("*")}
		until --fx == 0
		OK()
	}

	fun testLoop(floops:int) {
		let	lx = 0;
		let lloops=floops;

		write("testLoop..")
		while floops>0 do
			++lx
			floops-=1
		..
		TestHelper.assert(lx==lloops,"error in testLoop")
		//test real loop
		lx=1000
		loop
			lx-=1
			if lx==0 do break ..
		..
		OK()
	}

	fun testIf(){}

	fun testWhile(){}

	fun testCase() {
		var lx:int=5;
		write("testCase..")
		case lx
		of 1,1+1,1+2:	error("1")
		of 4:					error("2")
		of 5:					writeLn("case 5 selected") //must be selected
		of 12:				error("3")
		else					error("4")
		..
		OK()
	}

	fun testFinally() {
 		write("Test finally..")
 		return

	finally
		write("FINALLY passed correctly")
		OK()
	}

	fun testStatements(){
		testRepeat(1000)
		testLoop(1000)
		testIf()
		testWhile()
		testCase()
		testFinally()
	}

//################################
//################################

	fun logOpsTest() {
	let
		lt=true
		lf=false;

		write("logOperationTest..")
		assert(not (lt and lf), "boolean and error")
		assert(lt or lf, "boolean or error")
		OK()
	}


//########

	var	Depth:int=0

	fun
		incr(i:int):int {return i+1}
		decr(i:int):int {return i-1}

	fun testRecursion(fx:int) {
		write("Recursion..")
		write("*")
		Depth = incr(Depth)		//Depth+=1
		if fx>0 { testRecursion(fx-1) }
		Depth = decr(Depth) //Depth-=1
		if Depth==0 {
			write("out")
		}
		//OK()
	}

	fun testMemory(fsize:int) {
		precond fsize>0;
		var	lptr: address = nil;
		write("TEST MEMORY..")
		lptr = SYSTEM.allocate(fsize)
		write("allocated..")
		SYSTEM.free(lptr)
		write("deallocated..")
		OK()
	}

	fun testIndex() {
		var	ls:seq(char,10);
		let i=0;

		write("testIndex(must be 'alex 1234')..")
		ls[i]='a'
		ls[++i]='l'
		ls[++i]='e'
		ls[++i]='x'
		ls[++i]=' '
		ls[++i]='1'
		ls[++i]='2'
		ls[++i]='3'
		ls[++i]='4'
		ls[++i]=char(0)
		write(ls)
		OK()
	}

	fun testVarParam(var fvar:int) {
		write("Test VAR param(value must be 777)..");
		write("variable parameter is ");
		writeInt(fvar);
		OK();
	}

	fun testFiles() {
	var
		lf			:IO.File
		i,lsize	:int
		lok			:bool

		fun printCh(ff:IO.File){ //read char and print it
			precond ff # IO.NilFile;
			Console.writeChar(char(IO.fread(ff)))
		}

		do
		lf=IO.fopen("test.als") //open this file
		assert(lf#IO.NilFile,"cannot open file")
		lsize=IO.fsize(lf)		//get file size
		i=0
		while i<lsize { //print all the file to console
			printCh(lf)
			i+=1
		}

	finally //finally close the file
		lok = IO.fclose(lf) //close the file
		if not lok do error("cannot close file")..
		writeLn("file closed")
	}

	//Test file creation and writing
	fun testCreateFile() {
		let
			i=100
			lfile = IO.fcreate("xxx.txt")
			lok = false;

		//var	lfile:IO.File;
		assert(lfile#IO.NilFile,"cannot create file")
		while i>0 do
			lok = IO.fwrite(lfile,'X')
			--i
		..
		lok = IO.fclose(lfile)
	}

/*
	func testFileStat()
	var
		lf:IO.File
		lok:bool
		lstat:IO.FileInfo
	do
		lf 	= IO.fopen("test.als")
		lok = IO.finfo(lf, lstat)
		if (not lok) Error("cannot get file statistic") ..
	finally
		lok = IO.fclose(lf)
	..testFileStat
*/

	cluster MyGroup
		const
			c1=100
			c2=200
			c3=300
		type
			LocalInt = int

		//func One():int	return 1	..One
	end MyGroup

	@testGroup(){
		let	lx = MyGroup.c1;
		write("TEST GROUP..")
		writeInt(lx)	write(",")
		writeInt(MyGroup.c2)	write(",")
		writeInt(MyGroup.c3)
		OK()
	}


//module TestFunctionType
	@FF1(in fs:Strings.String) = writeLn(fs) ..
	@FF2(i,j:int)= ..

	type ffuu = @(int,int)

/*
	func testFunctionType()
	var
		lf	:func(int,int)
		lfs :func(in Strings.String)
		lff :func(int):func(int) 			//function return function
	do
		lf 	= FF2
		lfs = FF1
		//lfs("CALLING FORMAL FUNCTION")

		//lff = FF2
		//lfs = actualFunction
		//lfs("Formal Function Go")
	..testFunctionType
*/


//end module
	fun	failPrecond(fval :int) {
		precond fval<10 //this precondition must be failed by caller
		raise TestHelper.TestError
	}

	fun testPrecond():bool {
		//write("precondition test..")
		try
			failPrecond(100)
		catch SYSTEM.PrecondEx {
			return true
			//writeLn("OK-precondition failed as needed")
		else
			return false
			//writeLn("ERROR - precondition failed WRONG")
		}
	}

	fun testTrueFalse():bool {
		var lb,lres:bool;
		//write("testTrueFalse..")
		return not (true and false) or (true or false)
	}

	fun inout(in fin:Record2d, out fout:Record2d) {
		fout = fin
	}

/*
	func testInOutParams()
	do
	end testInOutParams
*/

	fun testStringConstantInit() {
		var	lb:seq(char,30)="TestingString";
		write("testStringConst..")
		Con.print (lb)
		writeLn(" - if text is 'TestingString' then OK")
		OK()
	}

	fun testAll() {
		writeLn("#nModule Tests STARTED:")
		testTypes()
		testStatements()



		testIndex()
		//testEnum()
		testRecursion(20)
		testMemory(1000)
		testRepeat(1000)
		lint = 777
		testVarParam(var lint)

		testGroup()
//		testFiles() //Program exited with return code: 0
//		T.testCreateFile()
//		T.testFileStat()
		logOpsTest()
		Suite.test(testPrecond,"test precondition")
		Suite.test(testTrueFalse, "test boolean expressions")
		writeLn("END OF TESTS")
	}

do
	//testAll()
	//Con.writeLn(" Daddy is very big popa")
end Tests.

★★★

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

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

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

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

только понятно, что это никому не надо, кроме интереса чисто академического. :)

alysnix ★★★
() автор топика

Ачивка открыта, поздравляю.

Nervous ★★★★★
()

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

Питон-стайл и паскаль-стайл:

	import
		SYSTEM
		Strings
		Con = Console
		IO
		Suite = TestHelper

	alias
		assert	= TestHelper.assert
		error		= TestHelper.error
		write		= Con.write
		writeLn	= Con.writeLn
		writeInt= Con.writeDec
		OK 			= TestHelper.ok

Си-стайл и руст-стайл:

	fun testLocalPointer():bool {
		const Val = 777;
		let lx=0;
		var lp:^int = addr(lx);

		lp^=Val;
		return lx==Val
	}
Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)

Очередной убийца Си++?

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

только понятно, что это никому не надо, кроме интереса чисто академического. :)

Если чисто ради интереса, то имхо лучше писать оптимизирующий компилятор самому. Вот где приключений…

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

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

тут есть синтаксический прикол

начало блока может обозначаться как:
{  //си стайл
do  //аля паскаль стайл, но там begin.
:  //мой стиль

конец блока:
}
end
..
то есть записи эквиваленты
if bool {x=0}
if bool: x=0 ..
if bool do x=0 end

аналогично функцию можно записать
fun ff():int { return 1}
fun ff():int = return 1 ..
fun ff():int do return 1 end

также fun = @

то есть функцию можно писать(для краткости):
@ff():int 
alysnix ★★★
() автор топика
Ответ на: комментарий от alysnix

Есть у меня тоже персональный язык, в котором режим синтаксиса переключается директивами. В нём можно делать:

или:

{ ... } - блок как в Си

или:

if ... then ... end - как в Паскале

или:

if ... then ... end:if - как в Ада, с обязательным обозначением, что именно мы закрываем end-ом.

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

еще деклараторы fun, type, alias, import, const, var - блочные, все что после такого декларатора обьявляется, считается соотв функцией, типом, алиасом и тепе. то есть функции можно обьявить списком

fun
  f(){....}
  ff(){...}

var
  x:int
  xx:int

и так далее

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

и само собой ООП.

definition TestTypes
type
	//StringVal = array	(char,any)
	MyEnum	= enum (one,two,three) //enumeration
	MySet 		= setof (MyEnum)

//test functional types definitions
type	
	FunctionType1 = fun(int,int) //void function taking two integers
	FunctionType2 = fun(ref int,ref int):int //takes two integers as var param and returns int
	FunctionType3 = fun():fun(int) //returns function of int parameter
	FunctionType4 = fun():FunctionType4 //function returns type of self

type
	UnicInt = unic(int) //unic type - is not compatible with int

	fun testTypes()
end TestTypes
//########################

module TestTypes
import
	Con = Console //import modules with aliasing
	Suit = TestHelper
	Strings

alias
	writeInt = Con.writeDec
	assert = Suit.assert;

//########################
//test class type 

type Point2d =	record //final
		//const	OriginX=0	OriginY=0
		var _x,_y: int
//#################
	virtual
		virt0():int {
			Con.writeLn("Basic implementation");
			return 0;
		}

		virt1():int {return 0 }

	fun
		x():int { return _x}
		y():int { return _y}

	fun
		add(in fp:Point2d){ _x+=fp._x _y+=fp._y }
		sub(in fp:Point2d){	_x-=fp._x _y-=fp._y	}
		mul(fmul:int) 		{	_x*=fmul	_y*=fmul	}

	fun
		dump(in fr:Point2d){
			writeInt(_x); Con.writeLn("")
			writeInt(_y); Con.writeLn("")
		}

	//*****************************
		ctor(){
			_x=0; 
			_y=0 	
		}
		
		ctor(fx,fy:int){	
			_x=fx;	
			_y=fy	
		}
		
		dtor() {
		
		}

		fun test(){
			//var lv:Point2d;
		}
		//new()=...
		//func delete()=...
	end

//test inheritance
type
	Point3d = record (Point2d)
		var _z:int

		//fun set(fx,fy,fz:int)
		fun _set(fx,fy,fz:int)	{
			_z=fz	_x=fx _y=fy
		}

		ctor(fx,fy,fz:int){
			//super(fx,fy)
      //var lx:int=x()
			_set(fx,fy,fz)
		}

		override virt0():int {
			Con.writeLn("Reimlemented")
			return 0
		}
	end

		//postponed realization
		//func Point3d.tes() ..tes


	//print 2d point values
	fun _printPoint2d(in fr:Point2d) {
    //nested function
		fun _printVal(fx:int, in fname:Strings.String){
			Con.write(fname) Con.write(":");
			writeInt(fx)
		}
	do
		_printVal(fr._x, "x");Con.writeLn("")
		_printVal(fr._y, "y");
	end

	//assign long values
	fun longAssignment(out fdst, in fsrc:Point2d) =
		fdst = fsrc
	..

	//test assignment to stack disposed record
	fun testRecord():bool =
		var	lr,lrr:Point2d;
		const C=33	CC=44;
		lr._x=C
		lr._y=CC
		assert(lr._x==C,	"wrong _x field 1")
		assert(lr._y==CC,	"wrong _y field 1" )
		longAssignment(out lrr,lr)// lrr=lr
		assert(lrr._x==C,	"wrong _x field 2")
		assert(lrr._y==CC,"wrong _y field 2" )
		_printPoint2d(lr);
		return true
		..

	//test access to a fields of inherited class
	fun testInheritance():bool {//test assignment to stack disposed record
		const	C1=111	C2=222	C3=333;
		var		lr:Point3d(C1,C2,C3); //test ctor
		if lr._x#C1 {return false}
		if lr._y#C2 {return false}
		if lr._z#C3 {return false}
		return true;
	}

	fun testVirtual():bool {
		var		lr	:Point2d(); //test ctor
		var		lrr	:Point3d(); //test ctor
		let lx=0;

		lx= lr	.virt0();
		lx= lrr	.virt0();
		return true
	}

	var StaticRecord: Point2d //static record

	//test pointer to static record
	fun testPointerToRecord():bool
	{
		var
			lr:Point2d
			lp:^Point2d;
		const
			CC = 77;

		Con.write("assignment go0 ")
		lp = addr(StaticRecord)
		lp^._y = CC
		Con.write("assignment go1 ")
		assert(lp^._y 					== CC, "testPointerToRecord - error1")
		assert(StaticRecord._y 	== CC, "testPointerToRecord - error2")

		lp = addr(lr)
		lp^._y = CC
		assert(lp^._y == CC, "testPointerToRecord - error3")
		assert(lr ._y == CC, "testPointerToRecord - error4")
		return true;
	}

	fun testTypes(){
		try
			Suit.test(testRecord, "test record")
			Suit.test(testPointerToRecord, "test pointer to record")
			Suit.test(testInheritance,"test inheritance")
			//Suit.test(testVirtual,"test virtual")
		//testAllocation()
		catch Suit.TestError do
			Con.writeLn("Error in types tests!!!")
			raise Suit.TestError
		end
	}


//module body code
do

end TestTypes.
alysnix ★★★
() автор топика
Ответ на: комментарий от LINUX-ORG-RU

Я самопальный конфиг распарсить не могу, а они тут языки изобретают. Афигели савсем! =)

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

alysnix ★★★
() автор топика

помесь сишки с паскалем с ml’ем кажется, сова начала расползаться по швам

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

Я и заинженерил всё так что бы был однопроходной рекурсивный спуск, просто у меня пару взаимоисключающих плюше и меня шатает =)

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от Deleted

паскаль-стайл Си-стайл и руст-стай

Да это же Kotlin.

EXL ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Я и заинженерил всё так что бы был однопроходной рекурсивный спуск, просто у меня пару взаимоисключающих плюше и меня шатает =)

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

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

Парсер написал, что ли?

не парсер. оно работает и исполняется. можно генерить код в:

инструкции проца(дедовский способ)

инструкции виртуальной машины(отцовский способ)

си-код (так мама делала)

исполняемое дерево - ну скажем так, ориентированный граф (свежо, молодежно).

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

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

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

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

только понятно, что это никому не надо, кроме интереса чисто академического. :)

«Академического»? Ты изучил состояние науки в этой отрасли? Сколько peer-reviewed статей прочитал? Где анализ, где постановка проблемы?

seiken ★★★★★
()

Прикольно выглядит. Сколько времени заняло?

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

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

Прикольно выглядит. Сколько времени заняло?

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

//declare variable ################
	void declVar(bool fexplicit_type) {
		Helper::ListOf<Object> lvars;
		Attr linit; //init expression
		Struct *ltype=nullptr;

		//parse list of names
		Object *lvar;
		do {
			cstr lname = testNewIdent();
			switch(_context.__block_kind) {

			case CContext::__ModuleBlock		:
			case CContext::__ClusterBlock		:
				lvar = new Tables::GlobalVar(lname);	break;

			case CContext::__ProcedureBlock	:
			case CContext::__FunctionBlock	:
				lvar = new Tables::LocalVar(lname);	break;

			default:
				error("var decl - wrong block kind");
				lvar=nullptr;
			}
			lvars.addLast(lvar); //safe for null pointer. else must be checked for null
			getSy();
		}
		while(canSkip(commaSy));

		Function *lctor=nullptr;
		Helper::ListOf<ActualParam> lpars;	//param list

		if(fexplicit_type) { //var explicit type must be given
			skipSy(colonSy);
			ltype=actualType();
			if(canSkip(assignSy)) { //init by assign
				typedExpr(linit,ltype);
			}
			else if(ltype->kind()==Struct::RECORD) { //init by default ctor
				if(canSkip(openBraceSy)) { //init by constructor with params
					lctor = parseCtorCall(ltype,lpars);
				}
				else {
					lctor = (static_cast<RecordStruct*>(ltype))->defaultCtor();//find appropriate constructor
					expect(lctor!=nullptr,"default ctor");
				}
			}
		}
		else { //derrived type is type of expression
			skipSy(assignSy);
			expr(linit);
			ltype = linit.struc();
		}

		if(ltype==nullptr) 	error(lvars.first()->name(),"-cannot resolve variable type");
		if(ltype->asize()<=0)error(lvars.first()->name(),"-variable has zero or unknown size");

		//put declared list into the scope
		//GenericVar *lvar = 0;
		while(true) {
			GenericVar *lvar = static_cast<GenericVar*>(lvars.removeFirst());
			if(lvar==nullptr) break;

			lvar->setStruct(ltype);
			lvar->setExported(_context._definition);
			Scope::current()->addObject(lvar);
			if(linit.defined()) {
				//add init statements to the block
				int lsrcsize = linit.toEx()->esize(); //attribute has proper length for null terminated string, could be improved
				_context._currBlock->addStat(assignment1(lvar->attr(),lvar->struc()->size(), linit.toEx(),lsrcsize));
				//_context._currBlock->addStat(assignment1(lvar->attr(),lvar->struc()->size(), linit.toEx(),linit.struc()->size()));
				lvar->setInited();
			}
			else  if(lctor) { //call constructor
				_context._currBlock->addStat(Slan::CALL_CLASSPROC(lvar->attr(),lctor->body(),lpars.getChain()));
				lvar->setInited();
			}
		}
	};
alysnix ★★★
() автор топика
Ответ на: комментарий от alysnix

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

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

При чем тут диссертации? Научная работа начинается с изучения существующей литературы по теме.

а какая будет тема?

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

Так это к тебе вопрос, у тебя же «академический интерес» :)

а вы академик? по какому поводу интересуетесь?

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

а вы академик? по какому поводу интересуетесь?

Просто спрашиваю, какой в данном проекте «академический» интерес.

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

Просто спрашиваю, какой в данном проекте «академический» интерес.

«чисто академический интерес» это эвфемизм, принятый в научной среде для выражения «нах. никому не нужно»

alysnix ★★★
() автор топика

Сдаётся мне, кто-то Роберта Нистрома начитался.

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

Жаль, https://nim-lang.org/ у меня не открывается, похоже забанено Косяктелекомом.

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

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

Scala, Kotlin, Swift, Rust, Go, TypeScript, etc pascal, modula-2, modula-3, oberon, ada…

имена слева просто много читабельней.

alysnix ★★★
() автор топика

Теперь надо на нём операционку написать

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

Хз, мне отступы удобнее фигурных {} которые постоянно забываю дописывать (в JS например) в теле функции, ее содержание тоже надо выравнивать отступами даже если это не влияет на выполнение кода.

С отступами мне гораздо проще разделять одну большую функцию на две маленьких, дописав где-нибудь в середине объявление новой функции. В общем, отступы рулят.

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

Говнокодеры привыкли надеяться на скобки в теле функции и поэтому забивают на выравнивание кода. Python за это ругает, говнокодеры бесятся и хэйтят его :)

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

Хз, мне отступы удобнее фигурных {} которые постоянно забываю дописывать

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

if(a){
  if(b){
    if(c){
      ff();
      ...
      ...
      ...
      ...
    }
  }
  ff();
}

if a
  if b
    if c
      ff()
      ...
      ...
      ...
      ...
  ff()

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

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

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

{
...
}
{
...
}
alysnix ★★★
() автор топика
Ответ на: комментарий от alysnix

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

Не имею ничего против User.find(10) ибо это одна строка, а тело функции может достигать 100 строк и больше, и ты из-за скобок будешь тащиться взад-перед по коду?

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

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

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

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

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

Это проблема скобок. А если скобок много (вложенных), то код становится нечитабельным.

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

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

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

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

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

начало блока может обозначаться как:

{ //си стайл

do //аля паскаль стайл, но там begin.

: //мой стиль

перловенько. Но там ещё есть векторный и скалярный контекст и условия можно записывать как перед, так и после блока с кодом. Рекомендую.

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